From 4784f95081944946f5a8588f890f71190d3fc889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 11 Jun 2023 11:53:11 +0800 Subject: [PATCH 01/70] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=90=91?= =?UTF-8?q?=E4=B8=8B=E8=BF=98=E5=8E=9F=E6=8C=89=E9=92=AE=E7=9A=84=E6=96=87?= =?UTF-8?q?=E5=AD=97=E6=8F=90=E7=A4=BA=20(#652)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie/MainWindow.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Magpie/MainWindow.cpp b/src/Magpie/MainWindow.cpp index ceea9effc..9a26b1fa7 100644 --- a/src/Magpie/MainWindow.cpp +++ b/src/Magpie/MainWindow.cpp @@ -436,6 +436,11 @@ void MainWindow::_ResizeTitleBarWindow() noexcept { (int)std::floorf(rect.Height * dpiScale + 1), // 不知为何,直接向上取整有时无法遮盖 TitleBarControl SWP_SHOWWINDOW ); + + // 设置标题栏窗口的最大化样式,这样才能展示正确的文字提示 + LONG_PTR style = GetWindowLongPtr(_hwndTitleBar, GWL_STYLE); + SetWindowLongPtr(_hwndTitleBar, GWL_STYLE, + _isMaximized ? style | WS_MAXIMIZE : style & ~WS_MAXIMIZE); } } From 468f548432447cdc8d40d2314b4966c176f074ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 11 Jun 2023 13:36:28 +0800 Subject: [PATCH 02/70] =?UTF-8?q?UI:=20=E4=B8=BA=E5=BF=AB=E6=8D=B7?= =?UTF-8?q?=E9=94=AE=E9=80=89=E9=A1=B9=E6=B7=BB=E5=8A=A0=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=20(#653)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.App/Resources.language-en-US.resw | 6 ++++++ src/Magpie.App/Resources.language-zh-Hans.resw | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/Magpie.App/Resources.language-en-US.resw b/src/Magpie.App/Resources.language-en-US.resw index ed679202a..90b2f25aa 100644 --- a/src/Magpie.App/Resources.language-en-US.resw +++ b/src/Magpie.App/Resources.language-en-US.resw @@ -838,4 +838,10 @@ Choose the executable file to launch the program + + Monitor the rendering performance while scaling + + + Scale the foreground window or stop scaling + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-zh-Hans.resw b/src/Magpie.App/Resources.language-zh-Hans.resw index 264d5c860..117f20e66 100644 --- a/src/Magpie.App/Resources.language-zh-Hans.resw +++ b/src/Magpie.App/Resources.language-zh-Hans.resw @@ -838,4 +838,10 @@ 选择用于启动程序的可执行文件 + + 在缩放时监测渲染性能 + + + 缩放前台窗口或停止缩放 + \ No newline at end of file From 0225644290ef9f266057049f7db9ff0a0e40d1d0 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 13 Jun 2023 11:54:31 +0200 Subject: [PATCH 03/70] Translations update from Hosted Weblate (#650) * Added translation using Weblate (Indonesian) * Translated using Weblate (Russian) Currently translated at 100.0% (240 of 240 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ru/ * Translated using Weblate (Korean) Currently translated at 100.0% (240 of 240 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ko/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (240 of 240 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/pt_BR/ * Translated using Weblate (Indonesian) Currently translated at 48.3% (116 of 240 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/id/ * Translated using Weblate (Japanese) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ja/ --------- Co-authored-by: Farhan Makarim Co-authored-by: NightFox Co-authored-by: a6e5aa12f60f4a7a Co-authored-by: Vitor Sacramento Co-authored-by: animeojisan --- src/Magpie.App/Resources.language-id.resw | 409 +++++++++++++++++++ src/Magpie.App/Resources.language-ja.resw | 6 + src/Magpie.App/Resources.language-ko.resw | 33 +- src/Magpie.App/Resources.language-pt-BR.resw | 4 +- src/Magpie.App/Resources.language-ru.resw | 15 + 5 files changed, 456 insertions(+), 11 deletions(-) create mode 100644 src/Magpie.App/Resources.language-id.resw diff --git a/src/Magpie.App/Resources.language-id.resw b/src/Magpie.App/Resources.language-id.resw new file mode 100644 index 000000000..672bca435 --- /dev/null +++ b/src/Magpie.App/Resources.language-id.resw @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tentang + + + Pintasan salah + + + Simpan + + + Tekan kombinasi tombol untuk mengganti pintasan ini + + + Tentang + + + Bawaan + + + Beranda + + + Profil baru + + + Pilih window + + + Salin dari + + + Buat + + + Nama + + + Buka window baru untuk membuat profil + + + Profil baru + + + Profil + + + Konfigurasi penskalaan + + + Konfigurasi penskalaan + + + Lebih lanjut + + + Umum + + + Bahasa + + + Bawaan Windows + + + Mode portable + + + Buka lokasi file konfigurasi + + + Jalankan saat startup + + + Magpie akan tetap berjalan di belakang saat window utama ditutup + + + Munculkan app di system tray + + + Tema + + + Gelap + + + Bawaan windows + + + Terang + + + Mati + + + Nyala + + + Pintasan + + + Overlay di game + + + Pintasan overlay di game + + + Skala + + + Pintasan skala + + + Jalankan + + + Umum + + + Otomatis diterapkan ketika gambar ouput terlalu besar untuk muat di layar + + + Efek downscaling bawaan + + + Ekspor + + + Impor + + + Impor ScaleModels.json + + + Opsi lainnya + + + Mode penskalaan + + + Selalu jalan sebagai administrator + + + Anda harus jalan sebagai administrator untuk menggunakan pengaturan ini + + + Aktivasi + + + Hapus + + + Judul kosong + + + Beranda + + + Tunda dalam detik + + + Batal + + + Periksa pembaruan secara berkala + + + Unduh dan install + + + Catatan rilis + + + Ingatkan saya nanti + + + {} tersedia + + + Tautan lainnya + + + Pedoman kontribusi + + + Sering ditanyakan + + + Lisensi + + + Repositori Github + + + Tidak ada + + + Parameter + + + Opsi lainnya + + + Hapus + + + Pindah ke bawah + + + Pindah ke atas + + + Ganti nama + + + Oke + + + Ganti nama + + + Tambah efek + + + Hapus + + + Hapus + + + Sedang digunakan oleh profil: + + + Apakah kamu yakin ingin menghapus mode penskalaan ini? + + + Drag and drop tidak didukung saat jalan sebagai administrator + + + Drag untuk menyusun ulang + + + Pindah ke bawah + + + Pindah ke atas + + + Mode penskalaan baru + + + Mode penskalaan baru + + + Skala + + + Tinggi (piksel) + + + Lebar (faktor skala) + + + Lebar (piksel) + + + Tipe + + + Absolut + + + Faktor + + + Isi + + + Isi layar, gambar mungkin meregang + + + Pas + + + Atur faktor penskalaan setelah mengisi layar dengan penskalaan proporsional + + + Umum + + + Mode 3D game + + + Skala otomatis ketika berada di latar depan + + + Metode penangkapan + + + Monitor preferensi + + + Monitor yang berpotongan dengan window sumber + + + Mode penskalaan + + + Jalankan + + + Window sekarang: + + + Batal + + + Sudah dipakai + + + Hanya pintasan yang berawal dengan tombol Windows, Ctrl, Alt, atau Shift yang berlaku. + + + Tinggi (faktor skala) + + + Tidak ada + + + Nama + + + Buat + + + Salin dari + + + Atur faktor penskalaan relatif terhadap gambar input + + + Atur ukuran setelah penskalaan + + + Semua monitor + + + Monitor yang paling dekat dengan window sumber + + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-ja.resw b/src/Magpie.App/Resources.language-ja.resw index e36c8ef17..bd55f79f7 100644 --- a/src/Magpie.App/Resources.language-ja.resw +++ b/src/Magpie.App/Resources.language-ja.resw @@ -838,4 +838,10 @@ 実行ファイル + + スケーリング時のレンダリングパフォーマンスの監視 + + + 前面ウィンドウをスケーリング、またはスケーリングを停止 + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-ko.resw b/src/Magpie.App/Resources.language-ko.resw index 2d4211b29..90a306274 100644 --- a/src/Magpie.App/Resources.language-ko.resw +++ b/src/Magpie.App/Resources.language-ko.resw @@ -149,22 +149,22 @@ 타이머가 끝날 때 포그라운드 창을 스케일 - 지연된 스케일 + 타이머 - {}초 후에 스케일 + {}초 후 스케일 취소 - 지연 시간(초) + 카운트다운(초) 취소 - 이미 사용 중임 + 이미 사용 중 저장 @@ -296,7 +296,7 @@ 맞추기 - 비례 스케일링으로 화면을 채운 후 스케일링 인수를 설정합니다 + 비례 스케일링으로 화면을 채운 후에 스케일링 인수를 설정합니다 일반 @@ -374,7 +374,7 @@ 기본값 - [그래픽 캡처]와 [데스크탑 복제]로 제한됨 + [그래픽 캡처]와 [데스크탑 복제] 한정 제목 표시줄 캡처 @@ -479,7 +479,7 @@ 만들기 - 이 바로 가기를 변경하려면 키의 조합을 누르세요 + 이 바로 가기를 변경하려면 키 조합을 누르세요 만들기 @@ -591,7 +591,7 @@ 인수 - 스케일링 후 크기를 설정합니다 + 스케일링 한 후에 크기를 설정합니다 화면을 채웁니다. 이미지가 늘어날 수 있습니다 @@ -759,9 +759,24 @@ 프레임 통계 - 출력 이미지가 너무 커서 화면에 맞지 않을 때 자동으로 적용됩니다(특징을 한눈에 이해할 수 있도록 원문에 없는 아이콘을 추가했습니다. 무거운 알고리즘일수록 각진 부분을 뭉개서 부드럽게 합니다. 원문은 알파벳 순으로 정렬되어 있습니다.) + 출력 이미지가 너무 커서 화면에 맞지 않을 때 자동으로 적용됩니다(특징을 한눈에 이해할 수 있도록 원문에 없는 아이콘을 추가했습니다. 해당 번역은 다음 버전에 추가됩니다. 무거운 알고리즘일수록 각진 부분을 뭉개서 부드럽게 합니다. 원문은 알파벳순으로 정렬되어 있습니다.) 폰트 캐시 비활성화 + + 최대화 또는 전체 화면 창을 스케일링 하도록 허용 + + + JSON 파일 + + + 프로그램을 실행하려면 실행 파일 선택 + + + 실행용 실행 파일(exe) 바꾸기 + + + 실행 파일 + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-pt-BR.resw b/src/Magpie.App/Resources.language-pt-BR.resw index cf41eac0f..b1ce3d240 100644 --- a/src/Magpie.App/Resources.language-pt-BR.resw +++ b/src/Magpie.App/Resources.language-pt-BR.resw @@ -566,7 +566,7 @@ Simular tela cheia exclusiva durante o redimensionamento - Você precisa ativar a opção "Mostrar o aplicativo na área de notificação" para usar essa configuração + Você precisa ativar a opção "Exibir o aplicativo na área de notificação" para usar essa configuração Erro @@ -599,7 +599,7 @@ Importar modos de redimensionamento - Atualizar configurações + Configurações de Atualização Tempos diff --git a/src/Magpie.App/Resources.language-ru.resw b/src/Magpie.App/Resources.language-ru.resw index 222186b99..2c1e655f1 100644 --- a/src/Magpie.App/Resources.language-ru.resw +++ b/src/Magpie.App/Resources.language-ru.resw @@ -823,4 +823,19 @@ Выключить кэш шрифтов + + Разрешить увеличение развёрнутых или полноэкранных окон + + + JSON файл + + + Изменить исполняемый файл для запуска + + + Исполняемый файл + + + Выберите исполняемый файл для запуска программы + \ No newline at end of file From d9ef805e00604fb33036c4cca8ce51106d532861 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 14 Jun 2023 17:11:16 +0200 Subject: [PATCH 04/70] Translated using Weblate (Ukrainian) (#658) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/uk/ Co-authored-by: Dan --- src/Magpie.App/Resources.language-uk.resw | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Magpie.App/Resources.language-uk.resw b/src/Magpie.App/Resources.language-uk.resw index 4b008a031..b3feeec77 100644 --- a/src/Magpie.App/Resources.language-uk.resw +++ b/src/Magpie.App/Resources.language-uk.resw @@ -692,7 +692,7 @@ Відеокарта - Режими масштабування + Режим масштабування Запуск @@ -838,4 +838,10 @@ Виберіть виконуваний файл для запуску програми + + Відстежуйте продуктивність рендерингу під час масштабування + + + Масштабувати вікно переднього плану або зупинити масштабування + \ No newline at end of file From 82806e1c6b5fc59513603583007841490b6ba9a6 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Fri, 16 Jun 2023 02:53:43 +0200 Subject: [PATCH 05/70] Translated using Weblate (Portuguese (Brazil)) (#660) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/pt_BR/ Co-authored-by: Vitor Sacramento --- src/Magpie.App/Resources.language-pt-BR.resw | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Magpie.App/Resources.language-pt-BR.resw b/src/Magpie.App/Resources.language-pt-BR.resw index b1ce3d240..aa9b1135c 100644 --- a/src/Magpie.App/Resources.language-pt-BR.resw +++ b/src/Magpie.App/Resources.language-pt-BR.resw @@ -779,4 +779,10 @@ Arquivo JSON + + Monitorar o desempenho de renderização durante o redimensionamento + + + Redimensionar a janela em primeiro plano ou interromper o redimensionamento + \ No newline at end of file From 592b0693625a7300e4e3652b1d5fa00e1c160518 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 18 Jun 2023 02:40:02 +0200 Subject: [PATCH 06/70] Translated using Weblate (Spanish) (#664) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/es/ Co-authored-by: Andrus Diaz German --- src/Magpie.App/Resources.language-es.resw | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Magpie.App/Resources.language-es.resw b/src/Magpie.App/Resources.language-es.resw index 91a30a09b..926675eef 100644 --- a/src/Magpie.App/Resources.language-es.resw +++ b/src/Magpie.App/Resources.language-es.resw @@ -823,4 +823,25 @@ Total + + Archivo JSON + + + Archivo ejecutable + + + Permitir escalar ventanas maximizadas o de pantalla completa + + + Cambiar el archivo ejecutable para el inicio + + + Elija el archivo ejecutable para iniciar el programa + + + Supervise el rendimiento de renderizado mientras escala + + + Escale la ventana de primer plano o deje de escalar + \ No newline at end of file From bd4ef7ceb95d80422b05022d2aa2f3511eb56aea Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 19 Jun 2023 06:35:00 +0200 Subject: [PATCH 07/70] Translated using Weblate (Indonesian) (#668) Currently translated at 77.6% (188 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/id/ Co-authored-by: Farhan Makarim --- src/Magpie.App/Resources.language-id.resw | 216 ++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/src/Magpie.App/Resources.language-id.resw b/src/Magpie.App/Resources.language-id.resw index 672bca435..b687caa65 100644 --- a/src/Magpie.App/Resources.language-id.resw +++ b/src/Magpie.App/Resources.language-id.resw @@ -406,4 +406,220 @@ Monitor yang paling dekat dengan window sumber + + Skalakan otomatis ketika jendela kembali ke latar depan + + + Restore otomatis + + + Aktivasi + + + Skalakan window latar depan saat timer berakhir + + + Tunda penskalaan + + + Skalakan setelah {} detik + + + Opsi lebih lanjut + + + Hapus + + + Hapus + + + Apakah anda yakin mau menghapus profil ini? + + + Buka lokasi program + + + Ganti nama + + + Oke + + + Ganti nama + + + Susun ulang + + + Pindah ke bawah + + + Pindah ke atas + + + Susun ulang + + + Gagal parsing + + + Tidak ada + + + Perfoma + + + Kartu grafis + + + Tampilkan penghitung FPS + + + Izinkan latensi tambahan untuk meningkatkan performa + + + VSync + + + Umpan balik + + + Diskusi + + + Laporkan bug + + + Minta fitur + + + Versi + + + Cek pembaruan preview + + + Cek pembaruan otomatis + + + Cek pembaruan + + + Gagal mengecek pembaruan, silakan coba lagi nanti + + + Mengecek pembaruan + + + Batal + + + Unduh dan install + + + Catatan rilis + + + Coba lagi + + + {} tersedia + + + Magpie terbaru + + + Unduh gagal + + + Mengunduh + + + Menginstal + + + Tingkat lanjut + + + Matikan DirectFlip + + + Kursor + + + Gambar kursor + + + Sesuaikan kecepatan kursor saat diskalakan + + + Algoritma interpolasi + + + Bilinear + + + Nearest-neighbor + + + Faktor penskalaan + + + Kustom + + + Tanpa penskalaan + + + Sama dengan window sumber + + + Bawaan + + + Window sumber + + + Terbatas untuk Graphics Capture dan Desktop Duplication + + + Tangkap title bar + + + Cropping kustom + + + Bawah + + + Kiri + + + px + + + Kanan + + + Atas + + + Nonaktifkan pengubahan ukuran window saat diskalakan + + + Memberikan sedikit peningkatan performa. Namun, efek harus dikompilasi ulang setiap kali parameternya diubah + + + Membuat parameter efek sejajar + + + Pemberitahuan dan pop-up dari aplikasi tertentu akan diblokir + + + Mensimulasikan layar penuh eksklusif saat melakukan penskalaan + + + Anda harus mengaktifkan "Tampilkan aplikasi pada system tray" untuk menggunakan pengaturan ini + \ No newline at end of file From 0a12dbcaaeff604c3d66e5aa7dac5058df308628 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 29 Jun 2023 01:52:18 +0200 Subject: [PATCH 08/70] Translated using Weblate (Turkish) (#671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/tr/ Co-authored-by: Serdar Sağlam --- src/Magpie.App/Resources.language-tr.resw | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Magpie.App/Resources.language-tr.resw b/src/Magpie.App/Resources.language-tr.resw index 09bce72e3..d7ff1a885 100644 --- a/src/Magpie.App/Resources.language-tr.resw +++ b/src/Magpie.App/Resources.language-tr.resw @@ -838,4 +838,10 @@ Çalıştırılabilir dosya + + Ölçeklendirme sırasında işleme performansını izle + + + Ön plan penceresini ölçeklendir veya durdur + \ No newline at end of file From 20e1a00a0905601899e7da269255d1d476b81c0f Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 12 Jul 2023 23:07:22 +0800 Subject: [PATCH 09/70] docs: add fil08 as a contributor for translation (#677) * docs: update README.md [skip ci] * docs: update README_ZH.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 1 + README_ZH.md | 1 + 3 files changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 5cfef4953..283f83604 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -211,6 +211,15 @@ "contributions": [ "translation" ] + }, + { + "login": "fil08", + "name": "fil08", + "avatar_url": "https://avatars.githubusercontent.com/u/125665523?v=4", + "profile": "https://github.com/fil08", + "contributions": [ + "translation" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index a98f7d329..075d2a57a 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ Thanks go to these wonderful people: Zoommod
Zoommod

🌍 + fil08
fil08

🌍 diff --git a/README_ZH.md b/README_ZH.md index bc28485bd..db5322996 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -109,6 +109,7 @@ Magpie 是一个轻量级的窗口缩放工具,内置了多种高效的缩放 Zoommod
Zoommod

🌍 + fil08
fil08

🌍 From 92153c8eb8031965d90cca5ffded31f8cc85dec7 Mon Sep 17 00:00:00 2001 From: WilliamHo Date: Thu, 13 Jul 2023 18:10:22 +0900 Subject: [PATCH 10/70] [fix] fix effect shader compile error (#678) --- src/Effects/Deband.hlsl | 4 ++-- src/Effects/ImageAdjustment.hlsl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Effects/Deband.hlsl b/src/Effects/Deband.hlsl index e3340750e..a67a4d7c1 100644 --- a/src/Effects/Deband.hlsl +++ b/src/Effects/Deband.hlsl @@ -73,11 +73,11 @@ float permute(float x) { return mod289((34.0*x + 1.0) * x); } float rand(float x) { return frac(x / 41.0); } // Helper: Calculate a stochastic approximation of the avg color around a pixel -float3 average(float2 pos, float range, inout float h) +float3 average(float2 pos, float r, inout float h) { const float2 pt = GetInputPt(); // Compute a random rangle and distance - float dist = rand(h) * range; h = permute(h); + float dist = rand(h) * r; h = permute(h); float dir = rand(h) * 6.2831853; h = permute(h); float2 o = float2(cos(dir), sin(dir)) * pt * dist; diff --git a/src/Effects/ImageAdjustment.hlsl b/src/Effects/ImageAdjustment.hlsl index b25438471..91807a9fa 100644 --- a/src/Effects/ImageAdjustment.hlsl +++ b/src/Effects/ImageAdjustment.hlsl @@ -100,8 +100,8 @@ SamplerState sam; float3 RGBtoHSV(float3 c) { float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); - float4 p = c.g < c.b ? float4(c.bg, K.wz) : float4(c.gb, K.xy); - float4 q = c.r < p.x ? float4(p.xyw, c.r) : float4(c.r, p.yzx); + float4 p = c.y < c.z ? float4(c.bg, K.wz) : float4(c.gb, K.xy); + float4 q = c.x < p.x ? float4(p.xyw, c.x) : float4(c.x, p.yzx); float d = q.x - min(q.w, q.y); float e = 1.0e-10; From 8b6d7ebddc2ee7b412e0950d275d49ef790a9166 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 18 Jul 2023 14:46:03 +0200 Subject: [PATCH 11/70] Translations update from Hosted Weblate (#675) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added translation using Weblate (Italian) * Translated using Weblate (Italian) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/it/ * feat: 支持意大利语 --------- Co-authored-by: fil08 Co-authored-by: 刘旭 <34770031+Blinue@users.noreply.github.com> --- src/Magpie.App/LocalizationService.cpp | 1 + src/Magpie.App/Magpie.App.vcxproj | 1 + src/Magpie.App/Magpie.App.vcxproj.filters | 3 + src/Magpie.App/Resources.language-it.resw | 788 ++++++++++++++++++++++ src/Magpie.Core/OverlayDrawer.cpp | 19 +- 5 files changed, 800 insertions(+), 12 deletions(-) create mode 100644 src/Magpie.App/Resources.language-it.resw diff --git a/src/Magpie.App/LocalizationService.cpp b/src/Magpie.App/LocalizationService.cpp index f07a528c1..5e5786a33 100644 --- a/src/Magpie.App/LocalizationService.cpp +++ b/src/Magpie.App/LocalizationService.cpp @@ -13,6 +13,7 @@ namespace winrt::Magpie::App { static std::array SUPPORTED_LANGUAGES{ L"en-us", L"es", + L"it", L"ja", L"ko", L"pt-br", diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index 0996df7a4..f18c67573 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -575,6 +575,7 @@ + diff --git a/src/Magpie.App/Magpie.App.vcxproj.filters b/src/Magpie.App/Magpie.App.vcxproj.filters index 96a0186b6..c6951dea6 100644 --- a/src/Magpie.App/Magpie.App.vcxproj.filters +++ b/src/Magpie.App/Magpie.App.vcxproj.filters @@ -294,6 +294,9 @@ Strings + + Strings + diff --git a/src/Magpie.App/Resources.language-it.resw b/src/Magpie.App/Resources.language-it.resw new file mode 100644 index 000000000..924328324 --- /dev/null +++ b/src/Magpie.App/Resources.language-it.resw @@ -0,0 +1,788 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Copia da + + + Home + + + Annulla + + + Già in uso + + + Attivazione + + + Ripristino automatico + + + Attiva + + + Pulisci + + + Finestra corrente: + + + Il titolo è vuoto + + + Ridimensiona la finestra in primo piano allo scadere del timer + + + Ridimensionamento ritardato + + + Ridimensiona dopo {}s + + + Ritardo in secondi + + + Annulla + + + Premi una combinazione di tasti per modificare questa scorciatoia + + + Scorciatoia non valida + + + Salva + + + Sono valide solo le scorciatoie che iniziano con il tasto Windows, Ctrl, Alt o Shift. + + + Riguardo a + + + Predefiniti + + + Home + + + Nuovo profilo + + + Apri una nuova finestra per creare un profilo + + + Nuovo profilo + + + Profili + + + Configurazione del ridimensionamento + + + Avanzate + + + Predefinita di Windows + + + Modalità portabile + + + Esegui all'avvio + + + Mostra l'app nell'area di notifica + + + Scorciatoia di ridimensionamento + + + Ridimensionamento + + + Avvia + + + Generali + + + Applicato automaticamente quando l'immagine di output è troppo grande per entrare nello schermo + + + Esporta + + + Importa + + + Importa ScaleModels.json + + + Altre opzioni + + + Modalità di ridimensionamento + + + Devi eseguire l'app come amministratore per usare questa impostazione + + + Esegui sempre come amministratore + + + Controlla periodicamente gli aggiornamenti + + + Scarica e installa + + + Note di rilascio + + + Ricordamelo dopo + + + {} è disponibile + + + Altri link + + + Linee guida per contribuire + + + Effetto di ridimensionamento predefinito + + + Nessuno + + + Cancella + + + Sposta in basso + + + Sposta in alto + + + Cancella + + + Cancella + + + Viene utilizzato dai seguenti profili: + + + Sei sicuro di voler eliminare questa modalità di ridimensionamento? + + + Il trascinamento non è supportato quando si usa l'app come amministratore + + + Trascina per riordinare + + + Sposta in basso + + + Sposta in alto + + + Nuova modalità di ridimensionamento + + + Ridimensiona + + + Copia da + + + Nessuno + + + Crea + + + Nome + + + Altezza (fattore di scala) + + + Altezza (pixel) + + + Larghezza (fattore di scala) + + + Larghezza (pixel) + + + Tipo + + + Assoluto + + + Imposta la dimensione dopo il ridimensionamento + + + Fattore + + + Impostare il fattore di scala relativo all'immagine in input + + + Riempi + + + Riempi lo schermo, l'immagine potrebbe essere allungata + + + Adatta + + + Generale + + + Modalità gioco 3D + + + Imposta il fattore di ridimensionamento dopo aver riempito lo schermo con il ridimensionamento proporzionale + + + Monitor preferito + + + Tutti i monitor + + + Monitor più vicino alla finestra di origine + + + Monitor attraversati dalla finestra di origine + + + Avvia + + + Cancella + + + Consenti ulteriore latenza per migliorare le prestazioni + + + VSync + + + Feedback + + + Discussioni + + + Segnala un bug + + + Richiedi una feature + + + Versione + + + Controlla gli aggiornamenti in anteprima + + + Controlla gli aggiornamenti automaticamente + + + Controlla gli aggiornamenti + + + Impossibile controllare gli aggiornamenti, riprova più tardi + + + Controllando gli aggiornamenti + + + Annulla + + + {} è disponibile + + + Magpie è aggiornata + + + Download fallito + + + In download + + + Installazione + + + Mostra cursore + + + Regola la velocità del cursore durante il ridimensionamento + + + Algoritmo di interpolazione + + + Bilineare + + + Nearest-neighbor + + + Fattore di scala + + + Personalizzato + + + Nessun ridimensionamento + + + Uguale alla finestra di origine + + + Predefinito + + + Finestra di origine + + + Limitato all'acquisizione grafica e alla duplicazione del desktop + + + Cattura barra del titolo + + + Ritaglio personalizzato + + + Parte inferiore + + + Sinistra + + + pixel + + + Destra + + + Parte superiore + + + Le notifiche e i popup di determinate applicazioni verranno bloccati + + + Devi attivare "Visualizza l'app nell'area notifiche" per utilizzare questa impostazione + + + Riduci a icona nella barra delle notifiche all'avvio + + + Il file di configurazione locale proviene da una versione sconosciuta e potrebbe non essere analizzato correttamente. + + + Continua + + + Mette i parametri dell'effetto in linea + + + Simula lo schermo intero esclusivo durante il ridimensionamento + + + Disabilita il ridimensionamento della finestra durante il ridimensionamento + + + Esci + + + Il file di configurazione globale proviene da una versione sconosciuta e potrebbe non essere analizzato correttamente. + + + Continua + + + Abilita modalità portabile + + + Queste impostazioni sono solo per gli sviluppatori + + + Disabilita la cache degli effetti + + + Salva il codice sorgente durante l'analisi degli effetti + + + Esci + + + Posizione del file di configurazione: +{} + + + Il file di configurazione non è un file JSON valido + + + Impossibile analizzare il file di configurazione + + + Impossibile leggere il file di configurazione + + + Esci + + + Finestra principale + + + Effetto sconosciuto + + + Alcuni effetti non possono essere analizzati + + + Importa ScaleModels.json + + + Impostazioni aggiornamenti + + + Versione + + + Modifica + + + Metodo di cattura + + + Monitoraggio delle prestazioni + + + importa le modalità di ridimensionamento + + + Esporta le modalità di ridimensionamento + + + VSync + + + Blocca + + + Statistiche dei frame + + + Passa alla frequenza dei fotogrammi + + + Passa ai tempi dei fotogrammi + + + Tempi + + + Passa agli effetti + + + Totale + + + Disabilita la cache dei caratteri + + + Passa ai passaggi + + + File eseguibile + + + Cambia il file eseguibile per l'avvio + + + Scegli il file eseguibile per avviare il programma + + + Esegui il ridimensionamento della finestra in primo piano o interrompi il ridimensionamento + + + Monitora le prestazioni di rendering durante il ridimensionamento + + + Crea + + + Riguardo a + + + Ridimensiona automaticamente quando la finestra torna in primo piano + + + Generali + + + Seleziona una finestra + + + Nome + + + Configurazione del ridimensionamento + + + Lingua + + + Tema + + + Apri il percorso del file di configurazione + + + Scuro + + + Scorciatoie + + + Magpie continuerà a funzionare in background dopo la chiusura della finestra principale + + + Predefinito di Windows + + + Chiaro + + + On + + + Off + + + Sovrapposizione in-gioco + + + Scorciatoia sovrapposizione in-gioco + + + FAQ + + + Licenza + + + Repository Github + + + Altre opzioni + + + Parametri + + + Nuova modalità di ridimensionamento + + + Rinomina + + + OK + + + Rinomina + + + Aggiungi effetto + + + Performance + + + Mostra il contatore FPS + + + Ridimensionamento automatico quando in primo piano + + + Metodo di cattura + + + Sei sicuro di voler eliminare questo profilo? + + + Altre opzioni + + + Apri il percorso del programma + + + Modalità di ridimensionamento + + + Cancella + + + Nessuno + + + OK + + + Rinomina + + + Rinomina + + + Riordina + + + Sposta in alto + + + Scheda grafica + + + Sposta in basso + + + Riordina + + + Analisi non riuscita + + + Scarica e installa + + + Riprova + + + Avanzate + + + Disabilita DirectFlip + + + Cursore + + + Note di rilascio + + + Dà un piccolo aumento delle prestazioni. Tuttavia, gli effetti devono essere ricompilati ogni volta che i loro parametri vengono modificati + + + Errore + + + Attenzione + + + Impostazioni sviluppatore + + + Modalità di debug + + + Considera gli avvisi come errori durante la compilazione degli effetti + + + Riavvia Magpie + + + Parametri di avvio + + + È necessario un riavvio affinché la modifica abbia effetto + + + Sblocca + + + Opacità + + + Consenti il ridimensionamento di finestre ingrandite o a schermo intero + + + FIle JSON + + \ No newline at end of file diff --git a/src/Magpie.Core/OverlayDrawer.cpp b/src/Magpie.Core/OverlayDrawer.cpp index 67fdff363..7c390bc1a 100644 --- a/src/Magpie.Core/OverlayDrawer.cpp +++ b/src/Magpie.Core/OverlayDrawer.cpp @@ -350,18 +350,16 @@ void OverlayDrawer::_BuildFontUI(std::wstring_view language, const std::vector Yu Gothic UI // 韩语/朝鲜语 -> Malgun Gothic // 参见 https://learn.microsoft.com/en-us/windows/apps/design/style/typography#fonts-for-non-latin-languages - - extraFontPath = StrUtils::UTF16ToUTF8(GetSystemFontsFolder()); - extraFontPath.push_back(L'\\'); if (language == L"zh-hans") { // msyh.ttc: 0 是微软雅黑,1 是 Microsoft YaHei UI - extraFontPath += "msyh.ttc"; + extraFontPath = StrUtils::Concat(StrUtils::UTF16ToUTF8(GetSystemFontsFolder()), "\\msyh.ttc"); extraFontNo = 1; extraRanges = ImGuiHelper::GetGlyphRangesChineseSimplifiedOfficial(); } else if (language == L"zh-hant") { // msjh.ttc: 0 是 Microsoft JhengHei,1 是 Microsoft JhengHei UI - extraFontPath += "msjh.ttc"; + extraFontPath = StrUtils::Concat(StrUtils::UTF16ToUTF8(GetSystemFontsFolder()), "\\msjh.ttc"); extraFontNo = 1; extraRanges = ImGuiHelper::GetGlyphRangesChineseTraditionalOfficial(); } else if (language == L"ja") { // YuGothM.ttc: 0 是 Yu Gothic Medium,1 是 Yu Gothic UI - extraFontPath += "YuGothM.ttc"; + extraFontPath = StrUtils::Concat(StrUtils::UTF16ToUTF8(GetSystemFontsFolder()), "\\YuGothM.ttc"); extraFontNo = 1; extraRanges = fontAtlas.GetGlyphRangesJapanese(); } else if (language == L"ko") { - extraFontPath += "malgun.ttf"; + extraFontPath = StrUtils::Concat(StrUtils::UTF16ToUTF8(GetSystemFontsFolder()), "\\malgun.ttf"); extraRanges = fontAtlas.GetGlyphRangesKorean(); } } From 7184f3406d185bba05ab40391c9479e04f25f456 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 22 Jul 2023 15:45:57 +0200 Subject: [PATCH 12/70] Translated using Weblate (Russian) (#681) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ru/ Co-authored-by: NightFox --- src/Magpie.App/Resources.language-ru.resw | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Magpie.App/Resources.language-ru.resw b/src/Magpie.App/Resources.language-ru.resw index 2c1e655f1..4b2dfb714 100644 --- a/src/Magpie.App/Resources.language-ru.resw +++ b/src/Magpie.App/Resources.language-ru.resw @@ -640,7 +640,7 @@ Не увеличивать
- То же, что и в исходном окне + Как в исходном окне По умолчанию @@ -838,4 +838,10 @@ Выберите исполняемый файл для запуска программы + + Отслеживание производительности отрисовки при увеличении + + + Увеличение переднего окна или останов увеличения + \ No newline at end of file From 9e71e7f4679eb7ef57d04dca7af34848d91b925f Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 24 Jul 2023 04:19:04 +0200 Subject: [PATCH 13/70] Translated using Weblate (Turkish) (#683) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/tr/ Co-authored-by: Serdar Sağlam --- src/Magpie.App/Resources.language-tr.resw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Magpie.App/Resources.language-tr.resw b/src/Magpie.App/Resources.language-tr.resw index d7ff1a885..3245749f9 100644 --- a/src/Magpie.App/Resources.language-tr.resw +++ b/src/Magpie.App/Resources.language-tr.resw @@ -286,7 +286,7 @@ Windows varsayılanı - Açık + Beyaz Kapalı @@ -782,7 +782,7 @@ Düzenle - Profiller + Profil oluştur Yakalama yöntemi From 6eb6b3a5c5ce4572683a61cf9cf960559048a8eb Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Wed, 26 Jul 2023 16:26:37 +0200 Subject: [PATCH 14/70] Translated using Weblate (Italian) (#688) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/it/ Co-authored-by: Hexaae --- src/Magpie.App/Resources.language-it.resw | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Magpie.App/Resources.language-it.resw b/src/Magpie.App/Resources.language-it.resw index 924328324..3e51ce26f 100644 --- a/src/Magpie.App/Resources.language-it.resw +++ b/src/Magpie.App/Resources.language-it.resw @@ -293,7 +293,7 @@ Fattore - Impostare il fattore di scala relativo all'immagine in input + Impostare il fattore di scala relativo all'immagine in entrata Riempi @@ -329,7 +329,7 @@ Avvia - Cancella + Elimina Consenti ulteriore latenza per migliorare le prestazioni @@ -398,7 +398,7 @@ Bilineare - Nearest-neighbor + Vicino più ravvicinato Fattore di scala @@ -630,10 +630,10 @@ Chiaro - On + Attivato - Off + Disattivato Sovrapposizione in-gioco @@ -696,7 +696,7 @@ Modalità di ridimensionamento - Cancella + Elimina Nessuno From d74a2ae957f51004d64c8a70ee19a005610f6c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=94=B8=E7=BE=9A?= <2842850481@qq.com> Date: Wed, 2 Aug 2023 09:49:19 +0800 Subject: [PATCH 15/70] Port Anime4K_Restore_S variant (#693) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Port Anime4K_Restore_S variant * Port Anime4K_Restore_Soft_S variant the same way * Fix Anime4K_Restore_Soft_S sort name * Optimize Anime4K_Restore_S and Soft variant * Minor optimization --------- Co-authored-by: 刘旭 <34770031+Blinue@users.noreply.github.com> --- src/Effects/Anime4K/Anime4K_Restore_L.hlsl | 2 +- src/Effects/Anime4K/Anime4K_Restore_M.hlsl | 2 +- src/Effects/Anime4K/Anime4K_Restore_S.hlsl | 298 ++++++++++++++++++ .../Anime4K/Anime4K_Restore_Soft_L.hlsl | 2 +- .../Anime4K/Anime4K_Restore_Soft_M.hlsl | 2 +- .../Anime4K/Anime4K_Restore_Soft_S.hlsl | 298 ++++++++++++++++++ .../Anime4K/Anime4K_Restore_Soft_UL.hlsl | 2 +- .../Anime4K/Anime4K_Restore_Soft_VL.hlsl | 2 +- src/Effects/Anime4K/Anime4K_Restore_UL.hlsl | 2 +- src/Effects/Anime4K/Anime4K_Restore_VL.hlsl | 2 +- src/Effects/Effects.vcxproj | 6 + src/Effects/Effects.vcxproj.filters | 6 + src/Updater/PackageFiles.h | 2 + 13 files changed, 618 insertions(+), 8 deletions(-) create mode 100644 src/Effects/Anime4K/Anime4K_Restore_S.hlsl create mode 100644 src/Effects/Anime4K/Anime4K_Restore_Soft_S.hlsl diff --git a/src/Effects/Anime4K/Anime4K_Restore_L.hlsl b/src/Effects/Anime4K/Anime4K_Restore_L.hlsl index 41a79c1df..1d0dab8f3 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_L.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_L.hlsl @@ -4,7 +4,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_1 +//!SORT_NAME Anime4K_Restore_2 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_M.hlsl b/src/Effects/Anime4K/Anime4K_Restore_M.hlsl index 6e8e03345..3b6b15760 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_M.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_M.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_0 +//!SORT_NAME Anime4K_Restore_1 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_S.hlsl b/src/Effects/Anime4K/Anime4K_Restore_S.hlsl new file mode 100644 index 000000000..6ab79dcdf --- /dev/null +++ b/src/Effects/Anime4K/Anime4K_Restore_S.hlsl @@ -0,0 +1,298 @@ +// Anime4K_Restore_CNN_S +// 移植自 https://github.com/bloc97/Anime4K/blob/master/glsl/Restore/Anime4K_Restore_CNN_S.glsl + +//!MAGPIE EFFECT +//!VERSION 3 +//!OUTPUT_WIDTH INPUT_WIDTH +//!OUTPUT_HEIGHT INPUT_HEIGHT +//!SORT_NAME Anime4K_Restore_0 + + +//!TEXTURE +Texture2D INPUT; + +//!SAMPLER +//!FILTER POINT +SamplerState sam; + +//!TEXTURE +//!WIDTH INPUT_WIDTH +//!HEIGHT INPUT_HEIGHT +//!FORMAT R16G16B16A16_FLOAT +Texture2D tex1; + +//!TEXTURE +//!WIDTH INPUT_WIDTH +//!HEIGHT INPUT_HEIGHT +//!FORMAT R16G16B16A16_FLOAT +Texture2D tex2; + + +//!PASS 1 +//!DESC Conv-4x3x3x3 +//!IN INPUT +//!OUT tex1 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass1(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float3 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = INPUT.GatherRed(sam, tpos); + const float4 sg = INPUT.GatherGreen(sam, tpos); + const float4 sb = INPUT.GatherBlue(sam, tpos); + + // w z + // x y + src[i][j] = float3(sr.w, sg.w, sb.w); + src[i][j + 1] = float3(sr.x, sg.x, sb.x); + src[i + 1][j] = float3(sr.z, sg.z, sb.z); + src[i + 1][j + 1] = float3(sr.y, sg.y, sb.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(src[i - 1][j - 1], float3x4(-0.19288683, -0.21397883, 0.111997396, -0.04791413, -0.26682988, -0.06144587, -0.03601853, -0.16693151, 0.038494494, -0.16651472, 0.147657, -0.083003886)); + result += mul(src[i - 1][j], float3x4(-0.14286195, 0.08746566, -0.40107322, 0.12390977, -0.33392772, -0.18703035, -0.21326795, 0.04780781, -0.15155545, -0.0010025925, -0.1554875, -0.10676251)); + result += mul(src[i - 1][j + 1], float3x4(0.28095165, 0.022872915, -0.21342312, -0.29982176, 0.025937587, -0.055012174, -0.33779636, 0.0015666655, 0.076416336, 0.06656033, -0.1557806, 0.1078894)); + result += mul(src[i][j - 1], float3x4(-0.31584853, 0.07527119, 0.30713862, -0.34014285, -0.50103146, -0.07217874, 0.512807, -0.09597398, -0.32097813, -0.051580857, -0.022466356, 0.01148551)); + result += mul(src[i][j], float3x4(-0.026032459, -0.04193211, 0.37703893, -0.031916667, -0.27421117, 1.0906446, -0.049654085, -0.19814016, 0.07819544, 0.06003738, 0.1405805, -0.0064135445)); + result += mul(src[i][j + 1], float3x4(0.041450135, 0.11319654, -0.23237701, 0.08443178, 0.53344345, 0.30857387, -0.057264958, -0.1575803, 0.2325609, -0.027797326, -0.04544767, -0.18720597)); + result += mul(src[i + 1][j - 1], float3x4(0.2531829, -0.074966915, -0.27800754, -0.3146097, 0.20126024, -0.5380133, -0.15082566, -0.19021043, 0.29951036, 0.17123336, -0.01681872, -0.12574998)); + result += mul(src[i + 1][j], float3x4(0.25203633, 0.19882993, 0.14906439, 0.13593598, 0.40712556, 0.084902965, 0.42969635, 0.2961132, -0.057267334, -0.030388135, 8.8084314e-05, 0.0210724)); + result += mul(src[i + 1][j + 1], float3x4(-0.13459359, -0.12199573, 0.12591946, 0.24736497, 0.2033463, -0.09388599, -0.094370656, 0.1071285, -0.18479438, -0.066625565, 0.08279283, 0.20130983)); + result += float4(-0.011108127, -0.07481861, 0.07640154, 0.4964964); + + tex1[destPos] = result; + } + } +} + + +//!PASS 2 +//!DESC Conv-4x3x3x8 +//!IN tex1 +//!OUT tex2 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass2(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float4 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = tex1.GatherRed(sam, tpos); + const float4 sg = tex1.GatherGreen(sam, tpos); + const float4 sb = tex1.GatherBlue(sam, tpos); + const float4 sa = tex1.GatherAlpha(sam, tpos); + + // w z + // x y + src[i][j] = float4(sr.w, sg.w, sb.w, sa.w); + src[i][j + 1] = float4(sr.x, sg.x, sb.x, sa.x); + src[i + 1][j] = float4(sr.z, sg.z, sb.z, sa.z); + src[i + 1][j + 1] = float4(sr.y, sg.y, sb.y, sa.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(max(src[i - 1][j - 1], 0), float4x4(-0.056432575, 0.0028165397, -0.026325442, -0.14802271, 0.16885762, -0.062179096, -0.2332292, 0.17513658, -0.08011296, 0.02947316, 0.014771492, -0.17946689, 0.026012989, -0.09823925, 0.036625937, -0.06924322)); + result += mul(max(src[i - 1][j], 0), float4x4(-0.13571467, 0.09831142, 0.12911566, 0.06305893, -0.07188695, -0.20161287, 0.3858435, -0.21069056, -0.12294444, -0.1404628, -0.022659872, 0.23008968, 0.10969853, 0.17640765, 0.39796907, 0.20413099)); + result += mul(max(src[i - 1][j + 1], 0), float4x4(-0.0061665224, 0.055102807, -0.0059629944, -0.021429887, 0.061626043, 0.16898955, -0.21215646, 0.16510476, 0.2238265, 0.19429931, 0.09874656, 0.06828208, -0.122404456, -0.00026717107, -0.28203064, -0.29979932)); + result += mul(max(src[i][j - 1], 0), float4x4(-0.22735378, 0.14538136, 0.11549746, 0.194148, -0.09841722, -0.0661309, 0.348576, -0.017375294, -0.044078812, 0.1298332, 0.04793373, -0.30687734, 0.08353025, 0.083519086, 0.10766399, 0.31796935)); + result += mul(max(src[i][j], 0), float4x4(0.048365135, -0.17566709, -0.33212858, -0.052667376, -0.26443407, -0.010216014, 0.1573303, 0.05725314, 0.08140953, -0.09664591, 0.076109104, -0.026773714, 0.07732627, 0.10188082, -0.28266954, -0.16230233)); + result += mul(max(src[i][j + 1], 0), float4x4(0.29931107, 0.117944, -0.10414009, 0.12795551, 0.12576093, 0.17082554, -0.15803693, 0.13430743, -0.025801308, -0.10797019, 0.0721032, 0.2825884, -0.11025257, 0.12798019, 0.081827976, -0.050441865)); + result += mul(max(src[i + 1][j - 1], 0), float4x4(-0.11827391, 0.08306765, -0.3430314, 0.07898041, -0.023839617, -0.019507334, 0.23176382, -0.40992323, 0.09411734, 0.38415068, -0.25845516, -0.29984522, 0.1470966, -0.0684779, -0.07071314, -0.026773235)); + result += mul(max(src[i + 1][j], 0), float4x4(0.19091596, 0.082110435, -0.5266589, -0.1744098, -0.015838385, -0.046316292, 0.023171103, -0.03731331, 0.2642396, 0.31824252, -0.041754793, -0.09525519, -0.14696182, 0.052168854, 0.039857205, -0.027555354)); + result += mul(max(src[i + 1][j + 1], 0), float4x4(0.15207373, 0.09845733, 0.0142631065, 0.096375965, 0.06089903, 0.17902578, -0.42391995, 0.22475442, 0.016356342, -0.06277531, -0.12173141, -0.18635495, -0.0013459618, 0.15725887, 0.019310836, 0.20293565)); + result += mul(max(-src[i - 1][j - 1], 0), float4x4(-0.18395247, 0.30672902, 0.09034339, 0.1821889, -0.0419004, -0.2169228, -0.14052129, 0.11006559, 0.1709272, 0.51062274, 0.13758625, -0.2242552, -0.030382963, 0.3357568, -0.26491287, 0.02501938)); + result += mul(max(-src[i - 1][j], 0), float4x4(0.040511727, 0.12523083, -0.27318433, 0.08388512, 0.25354835, 0.3404216, -0.2632471, -0.17784123, 0.2732347, 0.4468553, 0.084667034, -0.1856242, 0.034099877, -0.00954992, -0.32751867, -0.062207516)); + result += mul(max(-src[i - 1][j + 1], 0), float4x4(0.17564747, 0.11645554, -0.16362113, 0.105654195, -0.2762563, -0.1413764, 0.23264363, -0.14000498, 0.095402054, 0.0715738, -0.19346157, -0.028285999, 0.009799127, 0.04059529, 0.19688335, 0.1282381)); + result += mul(max(-src[i][j - 1], 0), float4x4(0.23575781, -0.11446148, -0.20504695, 0.035568226, 0.36890212, -0.85968876, -0.18545328, 0.33796397, -0.30916876, -0.10445518, -0.3046253, 0.33271998, -0.06263589, -0.2160114, -0.16383372, -0.31173357)); + result += mul(max(-src[i][j], 0), float4x4(0.20469664, 0.4039374, -0.070057206, 0.030353077, 0.39843914, -0.15490077, -0.24476516, 0.38238233, -0.21809858, 0.23496576, -0.051794037, 0.033664484, -0.14411364, -0.2515329, 0.124655396, -0.05818785)); + result += mul(max(-src[i][j + 1], 0), float4x4(-0.09065731, -0.16787091, 0.013269188, 0.23687351, -0.41504318, -0.048163068, 0.31760025, -0.33648986, 0.29752317, 0.2926866, 0.14408836, -0.33382463, -0.15873958, -0.121961035, 0.11797893, 0.09000567)); + result += mul(max(-src[i + 1][j - 1], 0), float4x4(0.13356976, 0.013763947, 0.012169505, -0.109594524, 0.03417223, 0.7031121, 0.65146804, 0.5250268, -0.50132495, -0.419648, 0.2940041, 0.83051753, -0.17595838, 0.1633008, -0.018587278, 0.079596795)); + result += mul(max(-src[i + 1][j], 0), float4x4(0.07570128, -0.1581438, 0.03904949, 0.14890033, -0.054611947, 0.17469402, -0.44252598, 0.036181703, -0.4981031, -0.37507218, -0.18466389, 0.2645845, 0.25189674, -0.025896115, 0.034307647, -0.020462232)); + result += mul(max(-src[i + 1][j + 1], 0), float4x4(-0.11645865, 0.02296537, 0.040909223, 0.015069485, 0.062284566, -0.22526766, 0.09241534, -0.32623053, 0.18208642, 0.3954284, 0.2884468, -0.25137675, -0.037232924, -0.10185309, -0.17956531, 0.018966453)); + result += float4(-0.16371979, -0.024620198, -0.035754893, 0.04176776); + + tex2[destPos] = result; + } + } +} + + +//!PASS 3 +//!DESC Conv-4x3x3x8 +//!IN tex2 +//!OUT tex1 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass3(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float4 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = tex2.GatherRed(sam, tpos); + const float4 sg = tex2.GatherGreen(sam, tpos); + const float4 sb = tex2.GatherBlue(sam, tpos); + const float4 sa = tex2.GatherAlpha(sam, tpos); + + // w z + // x y + src[i][j] = float4(sr.w, sg.w, sb.w, sa.w); + src[i][j + 1] = float4(sr.x, sg.x, sb.x, sa.x); + src[i + 1][j] = float4(sr.z, sg.z, sb.z, sa.z); + src[i + 1][j + 1] = float4(sr.y, sg.y, sb.y, sa.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(max(src[i - 1][j - 1], 0), float4x4(0.01921286, -0.26684764, -0.12663573, 0.31641877, -0.25313398, 0.12264074, 0.58750325, -0.14084283, 0.5837018, -0.042300556, -0.20435576, -0.009954825, 0.060783498, 0.05540401, 0.2205112, -0.06578902)); + result += mul(max(src[i - 1][j], 0), float4x4(-0.21930243, -0.03774968, 0.22615197, 0.18338196, 0.011201461, -0.271034, 0.00573116, -0.12248194, 0.47990513, 0.2982416, -0.1087603, -0.050099242, -0.07620939, -0.07148229, 0.03691984, -0.16796488)); + result += mul(max(src[i - 1][j + 1], 0), float4x4(-0.14962853, -0.053769328, 0.02387081, 0.22002189, 0.052237745, -0.26160842, -0.08603077, 0.012542448, 0.08119985, 0.075785555, -0.33437458, -0.43373227, -0.13206963, -0.08759176, -0.03288923, -0.09799959)); + result += mul(max(src[i][j - 1], 0), float4x4(-0.1305593, -0.5974288, 0.06058367, 0.08406488, 0.013692483, 0.06646377, 0.16469325, 0.08990975, 0.42217395, -0.11289523, -0.06165009, 0.48556912, -0.15702641, -0.19922857, -0.0035429662, -0.0022089656)); + result += mul(max(src[i][j], 0), float4x4(-0.1964807, 0.038099788, 0.21587034, 0.039734077, -0.07063389, 0.11604167, -0.24558097, -0.08900199, -0.7684516, -0.1037487, -0.09380674, 0.33144563, -0.16653742, 0.0028585843, -0.33774406, -0.0528696)); + result += mul(max(src[i][j + 1], 0), float4x4(-0.27298656, -0.05665099, 0.09661685, 0.19780266, 0.1025106, -0.22055034, -0.21218458, -0.040628925, 0.0095010325, 0.13118382, -0.42582452, -0.22197723, 0.21006055, -0.06189587, -0.15285942, -0.09526762)); + result += mul(max(src[i + 1][j - 1], 0), float4x4(-0.14494462, -0.046788953, 0.065877035, 0.09911713, 0.35096622, 0.16682479, 0.028363144, 0.36037162, 0.29413632, 0.28212717, -0.025364442, -0.3406269, 0.047262143, -0.11892685, -0.008032766, 0.29743317)); + result += mul(max(src[i + 1][j], 0), float4x4(-0.15191558, -0.36980554, 0.14555687, 0.0043930537, -0.012661432, 0.15737776, -0.115250416, 0.10324491, 0.24491951, -0.15575431, -0.27802598, 0.21959937, 0.18063772, 0.4455559, -0.09693302, 0.33382267)); + result += mul(max(src[i + 1][j + 1], 0), float4x4(0.2717801, 0.13452889, 0.14105384, 0.16324317, -0.40111846, 0.1154301, -0.0076733204, -0.09697362, 0.44306824, -0.02831414, -0.2153124, -0.12075326, 0.060776163, 0.30347148, -0.0036976219, -0.12070682)); + result += mul(max(-src[i - 1][j - 1], 0), float4x4(-0.39780128, -0.29875937, -0.12952097, 0.080333896, 0.07520163, 0.021689568, -0.23121156, -0.038140096, -0.1593877, 0.017156163, -0.06038025, 0.009244022, -0.13917233, 0.30957314, 0.243109, -0.104947075)); + result += mul(max(-src[i - 1][j], 0), float4x4(-0.07965157, 0.06776501, -0.13288979, 0.005851189, -0.08768168, -0.03689969, 0.12034646, 0.22441491, 0.14453568, -0.17648841, -0.3378289, -0.018329712, 0.11722939, -0.34161824, 0.08424494, -0.01400687)); + result += mul(max(-src[i - 1][j + 1], 0), float4x4(0.08153887, 0.07222914, -0.14663404, -0.038526025, -0.07385973, 0.18440577, 0.35890242, 0.17084727, 0.26345527, 0.15280858, -0.007446105, -0.024403179, -0.30336383, -0.22978698, 0.11612946, -0.23614909)); + result += mul(max(-src[i][j - 1], 0), float4x4(-0.07447396, 0.09023449, -0.13798, -0.086943336, -0.30787337, 0.15087669, 0.14418626, -0.03371195, 0.048989657, -0.13075387, -0.13458036, -0.059836224, 0.06495196, 0.269715, 0.3674355, 0.38956037)); + result += mul(max(-src[i][j], 0), float4x4(0.34981915, -0.048779126, 0.31717536, 0.38080826, -0.20149232, -0.82969636, -0.10167862, 0.6382858, 0.25976858, 0.4370118, -0.04724865, -0.10014156, 0.19380626, -0.080370255, 0.09578106, -0.035166856)); + result += mul(max(-src[i][j + 1], 0), float4x4(-0.026443917, 0.4132611, 0.01822534, 0.12742202, -0.26652107, -0.2996705, 0.30905882, 0.07989903, 0.38249823, 0.21486135, 0.025314959, -0.14717339, -0.13344015, -0.32088286, -0.2833883, -0.30973712)); + result += mul(max(-src[i + 1][j - 1], 0), float4x4(0.021517841, 0.006556378, 0.2025686, -0.12044382, -0.38583103, -0.0027515136, -0.06556736, -0.097090125, 0.04676486, -0.11954886, -0.051612873, 0.07831412, -0.18823163, -0.16542958, 0.04245155, 0.6437998)); + result += mul(max(-src[i + 1][j], 0), float4x4(-0.39475346, -0.2936861, 0.26768062, -0.28151843, 0.21935691, 0.2101108, -0.15455097, 0.19548604, 0.09188909, -0.020147726, 0.103328265, -0.12574542, -0.34167948, 0.07523185, -0.17669058, 0.62446547)); + result += mul(max(-src[i + 1][j + 1], 0), float4x4(-0.37661025, -0.29630858, 0.05451026, 0.1611643, 0.14079669, -0.2170294, -0.038716137, 0.13514164, -0.21235192, -0.07860726, -0.005749412, 0.025625167, -0.13297133, 0.33012658, -0.27434957, -0.18416783)); + result += float4(-0.0036821906, -0.050239526, -0.01355402, 0.00048220603); + + tex1[destPos] = result; + } + } +} + + +//!PASS 4 +//!DESC Conv-3x3x3x8 +//!IN INPUT, tex1 +//!BLOCK_SIZE 8 +//!NUM_THREADS 64 + +void Pass4(uint2 blockStart, uint3 threadId) { + uint2 gxy = Rmp8x8(threadId.x) + blockStart; + uint2 inputSize = GetInputSize(); + if (!CheckViewport(gxy)) { + return; + } + + float2 inputPt = GetInputPt(); + float2 pos = (gxy + 0.5f) * inputPt; + + // [ a, d, g ] + // [ b, e, h ] + // [ c, f, i ] + float4 a = tex1.SampleLevel(sam, pos + float2(-inputPt.x, -inputPt.y), 0); + float4 b = tex1.SampleLevel(sam, pos + float2(-inputPt.x, 0), 0); + float4 c = tex1.SampleLevel(sam, pos + float2(-inputPt.x, inputPt.y), 0); + float4 d = tex1.SampleLevel(sam, pos + float2(0, -inputPt.y), 0); + float4 e = tex1.SampleLevel(sam, pos, 0); + float4 f = tex1.SampleLevel(sam, pos + float2(0, inputPt.y), 0); + float4 g = tex1.SampleLevel(sam, pos + float2(inputPt.x, -inputPt.y), 0); + float4 h = tex1.SampleLevel(sam, pos + float2(inputPt.x, 0), 0); + float4 i = tex1.SampleLevel(sam, pos + float2(inputPt.x, inputPt.y), 0); + + float3 result = mul(max(a, 0), float4x3(0.15873, 0.17989138, 0.14648493, -0.017379675, -0.017363746, -0.019855022, 0.009670625, 0.0070157526, 0.0075994316, 0.025388412, 0.027231036, 0.024052646)); + result += mul(max(b, 0), float4x3(0.048195973, 0.041760173, 0.037366055, -0.115950756, -0.12887983, -0.12535639, 0.032125086, 0.03397254, 0.032950625, 0.01223746, 0.020822672, 0.0161561)); + result += mul(max(c, 0), float4x3(0.0890567, 0.094453335, 0.09014035, 0.016081346, 0.017434116, 0.020783134, -0.011775135, -0.010094134, -0.018522855, 0.072103254, 0.07940666, 0.065876864)); + result += mul(max(d, 0), float4x3(-0.04841196, -0.06963968, -0.056574684, 0.10912542, 0.11813441, 0.10643838, -0.013013885, -0.01562045, -0.013802797, 0.037505716, 0.04352026, 0.04645123)); + result += mul(max(e, 0), float4x3(-0.3472869, -0.36243078, -0.33530185, 0.23654196, 0.2305048, 0.22150646, -0.045226905, -0.041799217, -0.042511635, -0.10267792, -0.1123385, -0.10845448)); + result += mul(max(f, 0), float4x3(0.011987401, 0.012285043, 0.007813165, -0.15911353, -0.17523928, -0.1535267, 0.15675929, 0.16531634, 0.15948962, -0.09240023, -0.09513292, -0.084187366)); + result += mul(max(g, 0), float4x3(0.069052905, 0.07278333, 0.0756627, -0.012180326, -0.018794727, -0.031050753, -0.044663202, -0.04362803, -0.038904265, -0.008540197, -0.011201734, -0.01556625)); + result += mul(max(h, 0), float4x3(-0.08261173, -0.09042543, -0.07589266, 0.043515377, 0.045066774, 0.04037769, -0.06262993, -0.07469342, -0.058593787, 0.026696987, 0.028740842, 0.037405368)); + result += mul(max(i, 0), float4x3(0.07975598, 0.09597654, 0.08997132, -0.07844719, -0.07880916, -0.06835411, 0.05668995, 0.050163813, 0.053357534, -0.020040333, -0.019867316, -0.01907621)); + result += mul(max(-a, 0), float4x3(-0.017078733, -0.017393313, -0.008266595, -0.0033478448, -0.0027439648, -0.0042334674, -0.06354017, -0.062058125, -0.04652064, -0.010787706, -0.0062706997, -0.007573461)); + result += mul(max(-b, 0), float4x3(-0.019895451, -0.016341688, -0.008712399, 0.026231976, 0.023955572, 0.0216376, -0.061950512, -0.05481285, -0.05261985, -0.018804235, -0.016235247, -0.0131616965)); + result += mul(max(-c, 0), float4x3(-0.055628926, -0.063315354, -0.057192408, -0.0256364, -0.028660972, -0.02937357, -0.017604912, -0.020851422, -0.016070362, -0.0870202, -0.0832279, -0.07525406)); + result += mul(max(-d, 0), float4x3(0.062738225, 0.07106593, 0.061644047, -0.06068257, -0.06983662, -0.066070385, 0.024919355, 0.03227179, 0.028569462, -0.07866227, -0.098967604, -0.092128105)); + result += mul(max(-e, 0), float4x3(0.040397774, 0.047241107, 0.03962998, -0.09112752, -0.10057507, -0.09301817, 0.10833967, 0.101835825, 0.10027467, 0.27189335, 0.27433604, 0.26781923)); + result += mul(max(-f, 0), float4x3(-0.044211388, -0.042373534, -0.03658007, 0.113148406, 0.12423258, 0.107804194, -0.17081551, -0.18562958, -0.17475435, 0.09636739, 0.10763415, 0.093332425)); + result += mul(max(-g, 0), float4x3(-0.03798545, -0.047811143, -0.050768293, 0.018775463, 0.026812987, 0.03452908, 0.0055677597, 0.0039081173, -0.0017878668, -0.10728597, -0.12618187, -0.109045394)); + result += mul(max(-h, 0), float4x3(0.06359783, 0.064184755, 0.04934199, -0.009819327, -0.006616115, -0.007431496, 0.025055679, 0.024787048, 0.017360551, -0.047140837, -0.061695747, -0.06440822)); + result += mul(max(-i, 0), float4x3(0.060199022, 0.06482763, 0.059514645, 0.026998974, 0.028776823, 0.024897143, 0.17968474, 0.19337215, 0.16760105, 0.0075838566, 0.010503482, 0.011993149)); + result += float3(-0.0052927984, -0.0060193934, -0.0048643993); + + result += INPUT.SampleLevel(sam, pos, 0).rgb; + + WriteToOutput(gxy, result); +} diff --git a/src/Effects/Anime4K/Anime4K_Restore_Soft_L.hlsl b/src/Effects/Anime4K/Anime4K_Restore_Soft_L.hlsl index c63ff483b..5fcd04eff 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_Soft_L.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_Soft_L.hlsl @@ -4,7 +4,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_Soft_1 +//!SORT_NAME Anime4K_Restore_Soft_2 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_Soft_M.hlsl b/src/Effects/Anime4K/Anime4K_Restore_Soft_M.hlsl index 508b01ae4..051da91df 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_Soft_M.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_Soft_M.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_Soft_0 +//!SORT_NAME Anime4K_Restore_Soft_1 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_Soft_S.hlsl b/src/Effects/Anime4K/Anime4K_Restore_Soft_S.hlsl new file mode 100644 index 000000000..d15dd696a --- /dev/null +++ b/src/Effects/Anime4K/Anime4K_Restore_Soft_S.hlsl @@ -0,0 +1,298 @@ +// Anime4K_Restore_CNN_Soft_S +// 移植自 https://github.com/bloc97/Anime4K/blob/master/glsl/Restore/Anime4K_Restore_CNN_Soft_S.glsl + +//!MAGPIE EFFECT +//!VERSION 3 +//!OUTPUT_WIDTH INPUT_WIDTH +//!OUTPUT_HEIGHT INPUT_HEIGHT +//!SORT_NAME Anime4K_Restore_Soft_0 + + +//!TEXTURE +Texture2D INPUT; + +//!SAMPLER +//!FILTER POINT +SamplerState sam; + +//!TEXTURE +//!WIDTH INPUT_WIDTH +//!HEIGHT INPUT_HEIGHT +//!FORMAT R16G16B16A16_FLOAT +Texture2D tex1; + +//!TEXTURE +//!WIDTH INPUT_WIDTH +//!HEIGHT INPUT_HEIGHT +//!FORMAT R16G16B16A16_FLOAT +Texture2D tex2; + + +//!PASS 1 +//!DESC Conv-4x3x3x3 +//!IN INPUT +//!OUT tex1 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass1(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float3 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = INPUT.GatherRed(sam, tpos); + const float4 sg = INPUT.GatherGreen(sam, tpos); + const float4 sb = INPUT.GatherBlue(sam, tpos); + + // w z + // x y + src[i][j] = float3(sr.w, sg.w, sb.w); + src[i][j + 1] = float3(sr.x, sg.x, sb.x); + src[i + 1][j] = float3(sr.z, sg.z, sb.z); + src[i + 1][j + 1] = float3(sr.y, sg.y, sb.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(src[i - 1][j - 1], float3x4(0.10922428, -0.16249932, 0.15452726, -0.15669551, 0.053448875, -0.16528402, 0.01697721, -0.049275912, 0.20947173, -0.10576949, 0.19738325, -0.025417482)); + result += mul(src[i - 1][j], float3x4(-0.3285196, 0.15909512, -0.5273671, 0.23778777, -0.40508887, -0.0609677, -0.4188177, 0.11137456, -0.24131267, 0.10453423, -0.36216277, 0.053446792)); + result += mul(src[i - 1][j + 1], float3x4(0.23072472, -0.082083695, -0.0041477727, -0.09136237, 0.11958912, -0.312698, -0.15842685, -0.013882424, 0.10933724, 0.017880991, -0.022167003, 0.014662608)); + result += mul(src[i][j - 1], float3x4(-0.2789985, 0.054727737, 0.22577816, -0.49625716, -0.48472273, -0.011525487, 0.5354349, -0.08814955, -0.27021924, -0.044563178, 0.008232271, -0.13480483)); + result += mul(src[i][j], float3x4(-0.18203105, 0.09277001, 0.27071548, -0.17773713, -0.4335171, 1.2275106, -0.07663438, -0.29020032, 0.011992759, 0.060106967, 0.11002492, -0.046098012)); + result += mul(src[i][j + 1], float3x4(0.08363418, 0.063420765, -0.10278259, 0.09357691, 0.38670546, 0.13577081, 0.048631024, -0.024960777, 0.0846784, -0.057097007, 0.06049236, 0.042082917)); + result += mul(src[i + 1][j - 1], float3x4(0.12315548, -0.056513585, -0.09826642, -0.17079762, 0.06479095, -0.36984903, -0.12512982, 0.042867575, 0.08360464, 0.12835538, -0.005067881, 0.02542005)); + result += mul(src[i + 1][j], float3x4(0.18997705, 0.086363226, -0.0007131526, 0.19858918, 0.39745626, -0.0090341605, 0.27864447, 0.20052041, 0.010576528, -0.089242525, -0.025109483, -0.030768145)); + result += mul(src[i + 1][j + 1], float3x4(0.05427315, -0.060894873, 0.06548642, 0.095537595, 0.29116166, -0.16159569, -0.13293959, -0.112566955, 0.0059667625, 0.016041303, 0.03831561, 0.09869594)); + result += float4(0.0113532655, -0.06449327, 0.035503868, 0.5683031); + + tex1[destPos] = result; + } + } +} + + +//!PASS 2 +//!DESC Conv-4x3x3x8 +//!IN tex1 +//!OUT tex2 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass2(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float4 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = tex1.GatherRed(sam, tpos); + const float4 sg = tex1.GatherGreen(sam, tpos); + const float4 sb = tex1.GatherBlue(sam, tpos); + const float4 sa = tex1.GatherAlpha(sam, tpos); + + // w z + // x y + src[i][j] = float4(sr.w, sg.w, sb.w, sa.w); + src[i][j + 1] = float4(sr.x, sg.x, sb.x, sa.x); + src[i + 1][j] = float4(sr.z, sg.z, sb.z, sa.z); + src[i + 1][j + 1] = float4(sr.y, sg.y, sb.y, sa.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(max(src[i - 1][j - 1], 0), float4x4(-0.027102098, 0.2640691, 0.1169015, 0.030902913, 0.15404584, 0.1361459, -0.38066056, 0.096569136, -0.111836195, -0.0051853824, -0.0996669, -0.23538585, -0.07060754, -0.18889332, -0.10793357, -0.15154232)); + result += mul(max(src[i - 1][j], 0), float4x4(0.1378689, 0.21024452, 0.010976513, 0.0179521, -0.05993059, -0.28364083, 0.24486947, 0.21347582, -0.12522404, -0.16091396, 0.15499291, 0.08353191, -0.03342411, -0.08964405, 0.25111282, -0.07550899)); + result += mul(max(src[i - 1][j + 1], 0), float4x4(-0.06398718, 0.05763278, 0.021394925, 0.14780094, -0.033050716, 0.03346528, -0.0846797, 0.0125302235, 0.18018652, 0.24586707, 0.050538495, 0.09879243, -0.100035876, 0.043505374, 0.042692907, -0.08768257)); + result += mul(max(src[i][j - 1], 0), float4x4(-0.11572878, 0.0545887, 0.16437739, 0.2775331, 0.10323911, -0.18938646, -0.17097469, -0.188723, 0.085762165, 0.14605838, -0.15568069, -0.16947642, 0.09042493, -0.087587915, -0.041969277, 0.27252352)); + result += mul(max(src[i][j], 0), float4x4(0.21475963, -0.018211678, -0.5711054, -0.09235345, -0.20367791, -0.23041399, 0.16346097, 0.007901888, 0.12542121, 0.16807431, 0.09862575, 0.16968751, 0.28490388, 0.40945014, -0.22364445, 0.14460565)); + result += mul(max(src[i][j + 1], 0), float4x4(0.27512726, 0.14046481, -0.17684339, 0.102218024, -0.10503195, 0.3080809, 0.03681373, 0.2668656, -0.093752496, -0.07476867, 0.19900662, 0.06028286, -0.19815882, -0.0584525, 0.027984729, -0.02143819)); + result += mul(max(src[i + 1][j - 1], 0), float4x4(-0.16829525, -0.06818115, 0.0006509334, 0.01163159, 0.18918815, -0.10731989, -0.008126929, -0.47991323, -0.11022971, 0.19150843, 0.05272113, -0.34417602, 0.022882428, 0.1774031, 0.062597334, -0.09915319)); + result += mul(max(src[i + 1][j], 0), float4x4(0.32131585, 0.05668815, -0.34203658, 0.05542482, -0.008077225, 0.009148517, 0.10953332, -0.050969962, 0.09904077, 0.46938205, -0.5148919, -0.22275375, -0.10536104, -0.23662373, 0.002147416, -0.14256701)); + result += mul(max(src[i + 1][j + 1], 0), float4x4(-0.19335353, -0.103732094, 0.17156832, 0.0059756916, -0.118641876, 0.14529023, -0.18662338, 0.0447326, 0.026719248, 0.042491894, 0.026437795, 0.05601309, 0.08645617, 0.08365193, -0.039582565, 0.16612953)); + result += mul(max(-src[i - 1][j - 1], 0), float4x4(-0.014315469, 0.012588422, 0.037587024, 0.08707526, -0.08064868, -0.28149533, 0.27326405, 0.21468583, -0.04278333, 0.29369017, 0.18653142, 0.035729136, 0.079363555, 0.30725953, 0.0147137, 0.08527481)); + result += mul(max(-src[i - 1][j], 0), float4x4(0.06659263, 0.03452449, -0.33752796, 0.0066543026, 0.48697233, 0.019602561, -0.32033685, -0.20538871, 0.3089118, 0.4315903, -0.13524854, -0.10791581, 0.3315688, 0.13135147, -0.26904663, 0.142365)); + result += mul(max(-src[i - 1][j + 1], 0), float4x4(0.13619833, 0.045271892, -0.029841429, 0.010704955, -0.29257727, -0.10563375, 0.35345638, -0.06734038, -0.043791633, -0.0056891907, -0.078411415, 0.075443126, -0.05746597, -0.19959894, -0.12797245, 0.18837726)); + result += mul(max(-src[i][j - 1], 0), float4x4(0.25673476, 0.120482095, -0.23827696, -0.13557845, 0.300447, -0.3008584, -0.13834439, 0.5459493, -0.26155484, 0.06905137, 0.16247983, 0.039960653, -0.023218757, 0.07977591, -0.11354706, -0.25831422)); + result += mul(max(-src[i][j], 0), float4x4(0.0842605, 0.282916, 0.14062001, 0.06356874, 0.55912817, 0.1743876, -0.30324093, 0.052068707, -0.20756413, 0.27321506, -0.26560605, -0.27695876, -0.3927334, -0.5439608, 0.39293098, -0.001130203)); + result += mul(max(-src[i][j + 1], 0), float4x4(-0.021890296, -0.12703396, 0.06660714, -0.03164527, 0.0018722567, -0.26552317, 0.06978973, -0.24030049, 0.46008193, 0.5595346, 0.081981994, -0.038414747, -0.010446991, -0.56102365, -0.079274766, -0.01851302)); + result += mul(max(-src[i + 1][j - 1], 0), float4x4(0.052988984, 0.030581746, -0.06868741, 0.21545182, -0.5706256, -0.0034910638, 0.48361364, 0.9020033, -0.02242781, -0.13256042, 0.08997955, 0.21001706, -0.059571438, -0.040119104, -0.05029196, -0.127414)); + result += mul(max(-src[i + 1][j], 0), float4x4(-0.08275339, -0.05999088, 0.11068767, 0.014646892, -0.041986465, 0.1028236, -0.17218924, 0.026559748, -0.17412743, -0.38364175, 0.17410514, 0.13038695, 0.23155633, 0.2655843, 0.045085523, 0.13005458)); + result += mul(max(-src[i + 1][j + 1], 0), float4x4(-0.013383197, -0.064526096, 0.049046878, 0.015992291, 0.123987064, 0.0104690585, 0.07065378, -0.009824511, -0.036109775, 0.13384768, 0.29676288, -0.39475223, -0.009368096, -0.05666906, -0.09132696, -0.082638375)); + result += float4(-0.106538564, -0.065693766, -0.03790106, 0.04776706); + + tex2[destPos] = result; + } + } +} + + +//!PASS 3 +//!DESC Conv-4x3x3x8 +//!IN tex2 +//!OUT tex1 +//!BLOCK_SIZE 16 +//!NUM_THREADS 64 + +void Pass3(uint2 blockStart, uint3 threadId) { + uint2 gxy = (Rmp8x8(threadId.x) << 1) + blockStart; + uint2 inputSize = GetInputSize(); + if (gxy.x >= inputSize.x || gxy.y >= inputSize.y) { + return; + } + float2 inputPt = GetInputPt(); + + uint i, j; + + float4 src[4][4]; + [unroll] + for (i = 0; i <= 2; i += 2) { + [unroll] + for (j = 0; j <= 2; j += 2) { + float2 tpos = (gxy + uint2(i, j)) * inputPt; + const float4 sr = tex2.GatherRed(sam, tpos); + const float4 sg = tex2.GatherGreen(sam, tpos); + const float4 sb = tex2.GatherBlue(sam, tpos); + const float4 sa = tex2.GatherAlpha(sam, tpos); + + // w z + // x y + src[i][j] = float4(sr.w, sg.w, sb.w, sa.w); + src[i][j + 1] = float4(sr.x, sg.x, sb.x, sa.x); + src[i + 1][j] = float4(sr.z, sg.z, sb.z, sa.z); + src[i + 1][j + 1] = float4(sr.y, sg.y, sb.y, sa.y); + } + } + + [unroll] + for (i = 1; i <= 2; ++i) { + [unroll] + for (j = 1; j <= 2; ++j) { + uint2 destPos = gxy + uint2(i - 1, j - 1); + + if (i != 1 || j != 1) { + if (destPos.x >= inputSize.x || destPos.y >= inputSize.y) { + continue; + } + } + + float4 result = mul(max(src[i - 1][j - 1], 0), float4x4(0.024004154, -0.26474997, -0.5256586, 0.051624652, -0.16621786, 0.2964122, 0.6044247, -0.14335106, 0.17002718, -0.2679876, -0.30162668, 0.1273794, -0.17601459, -0.1782376, 0.104725115, -0.16351137)); + result += mul(max(src[i - 1][j], 0), float4x4(-0.121676154, 0.047741555, -0.06738679, -0.056402843, 0.004424971, -0.35099635, -0.073440626, 0.039784692, 0.15204315, -0.1165704, 0.11231046, -0.27369732, 0.33737272, -0.11880767, 0.09637475, -0.14709689)); + result += mul(max(src[i - 1][j + 1], 0), float4x4(-0.017987821, -0.08798823, -0.062515825, -0.046803873, -0.05871703, 0.27013004, 0.19397618, -0.052147817, 0.003271283, -0.0029015478, -0.07390092, -0.09348337, -0.1574738, 0.06750957, -0.07661155, 0.054327156)); + result += mul(max(src[i][j - 1], 0), float4x4(-0.15215784, -0.72508365, -0.3202069, 0.20295432, -0.19125701, 0.021401431, -0.051837035, -0.025939213, 0.25565025, -0.12872623, 0.13169816, 0.27377388, -0.008718429, -0.05864064, 0.028844763, 0.1144993)); + result += mul(max(src[i][j], 0), float4x4(-0.30012092, -0.1322455, -0.11868545, 0.09857058, 0.082795605, -0.075334676, -0.3752773, -0.02918163, -0.67764, -0.38598236, -0.21023573, 0.38274166, -0.07398165, -0.07213789, -0.28427607, 0.1266569)); + result += mul(max(src[i][j + 1], 0), float4x4(-0.37507388, 0.18809201, -0.21982779, 0.27208912, 0.022066567, -0.27627763, 0.12345216, -0.30041683, 0.017002959, -0.091398515, -0.25207692, -0.29253414, -0.08231422, -0.14665812, -0.07868529, -0.24562219)); + result += mul(max(src[i + 1][j - 1], 0), float4x4(0.08686712, 0.080837384, 0.20736577, 0.008233064, 0.14957365, 0.21801959, -0.04870689, 0.42149112, 0.27255878, 0.33320278, -0.08467146, 0.10381615, 0.055278245, 0.085710146, 0.009097151, 0.29092705)); + result += mul(max(src[i + 1][j], 0), float4x4(0.0012207404, -0.023874281, -0.027035477, 0.005157451, 0.19330226, 0.33711615, -0.16495204, 0.549021, 0.44879642, 0.1978837, -0.20492741, 0.28099406, 0.2631811, 0.40786585, -0.055340275, 0.2575511)); + result += mul(max(src[i + 1][j + 1], 0), float4x4(0.29127392, -0.06287165, 0.12715077, 0.14784902, -0.3183704, 0.42057636, -0.11483724, -0.3019506, 0.010730576, 0.29091576, -0.046116166, -0.23528357, -0.0037143505, 0.1191774, -0.06084074, 0.011641706)); + result += mul(max(-src[i - 1][j - 1], 0), float4x4(-0.2579205, 0.036545023, 0.11691888, 0.04996418, 0.21318026, 0.21370813, -0.14114271, 0.031217605, -0.06979331, -0.0690704, 0.04618086, 0.025164584, -0.10994228, 0.109930746, 0.103678934, 0.12193115)); + result += mul(max(-src[i - 1][j], 0), float4x4(-0.19843774, -0.11237926, 0.007291354, 0.16480611, -0.15669724, 0.46283355, 0.077065215, 0.112273656, 0.17143534, -0.19934891, -0.25481275, 0.034591813, -0.27032652, -0.2702769, 0.04816228, -0.031614583)); + result += mul(max(-src[i - 1][j + 1], 0), float4x4(-0.16307239, -0.11295217, 0.05861256, 0.14225823, -0.015648091, 0.11741865, 0.113366075, 0.023935538, 0.19560932, -0.10553561, -0.042583376, -0.048160724, -0.3116519, 0.13957061, -0.0044852323, -0.015472912)); + result += mul(max(-src[i][j - 1], 0), float4x4(-0.15629178, 0.06463271, -0.13176678, 0.025518289, -0.021733627, 0.22236359, 0.019508492, -0.11629477, 0.10801276, -0.021957984, -0.11272639, -0.03615053, -0.121420704, 0.2520835, 0.043395765, 0.1699031)); + result += mul(max(-src[i][j], 0), float4x4(0.2886654, 0.21755892, 0.21757497, 0.08442575, -0.109903164, -0.67295986, 0.22886126, -0.027185453, 0.3761606, 0.23199768, 0.05908783, -0.1496158, 0.10832971, -0.3530352, 0.20234483, -0.07615918)); + result += mul(max(-src[i][j + 1], 0), float4x4(0.11043024, 0.18943349, 0.42394367, 0.029350199, -0.15085667, 0.020204183, -0.081609115, 0.07907012, 0.33805525, 0.0066280114, 0.0018284445, 0.022983696, 0.004984607, 0.0429299, -0.14568979, -0.29143327)); + result += mul(max(-src[i + 1][j - 1], 0), float4x4(-0.16376027, -0.20387048, 0.06522074, 0.17484841, -0.13885716, -0.04380927, -0.03535832, -0.16978237, -0.004799155, -0.25407305, -0.039976966, -0.011992087, -0.22535577, -0.09583549, 0.0334331, 0.016292758)); + result += mul(max(-src[i + 1][j], 0), float4x4(-0.38688713, -0.20232083, 0.23887886, -0.10438324, -0.24170811, -0.074868314, 0.03977399, -0.22810821, -0.08257971, -0.11902456, 0.106009185, -0.078289054, -0.11932821, 0.024207884, 0.10070917, 0.79348284)); + result += mul(max(-src[i + 1][j + 1], 0), float4x4(-0.4018743, 0.050456528, 0.035341598, -0.03788609, 0.12964934, -0.44461823, 0.029031694, 0.29604837, -0.102386944, -0.13805065, 0.0055692918, 0.14659804, -0.22499937, 0.14680648, -0.3443954, -0.06994176)); + result += float4(-0.0063428865, 0.0057986965, -0.12526293, -0.059240736); + + tex1[destPos] = result; + } + } +} + + +//!PASS 4 +//!DESC Conv-3x3x3x8 +//!IN INPUT, tex1 +//!BLOCK_SIZE 8 +//!NUM_THREADS 64 + +void Pass4(uint2 blockStart, uint3 threadId) { + uint2 gxy = Rmp8x8(threadId.x) + blockStart; + uint2 inputSize = GetInputSize(); + if (!CheckViewport(gxy)) { + return; + } + + float2 inputPt = GetInputPt(); + float2 pos = (gxy + 0.5f) * inputPt; + + // [ a, d, g ] + // [ b, e, h ] + // [ c, f, i ] + float4 a = tex1.SampleLevel(sam, pos + float2(-inputPt.x, -inputPt.y), 0); + float4 b = tex1.SampleLevel(sam, pos + float2(-inputPt.x, 0), 0); + float4 c = tex1.SampleLevel(sam, pos + float2(-inputPt.x, inputPt.y), 0); + float4 d = tex1.SampleLevel(sam, pos + float2(0, -inputPt.y), 0); + float4 e = tex1.SampleLevel(sam, pos, 0); + float4 f = tex1.SampleLevel(sam, pos + float2(0, inputPt.y), 0); + float4 g = tex1.SampleLevel(sam, pos + float2(inputPt.x, -inputPt.y), 0); + float4 h = tex1.SampleLevel(sam, pos + float2(inputPt.x, 0), 0); + float4 i = tex1.SampleLevel(sam, pos + float2(inputPt.x, inputPt.y), 0); + + float3 result = mul(max(a, 0), float4x3(0.08631539, 0.09499331, 0.065609254, -0.023760278, -0.027293118, -0.022839671, -0.012447854, -0.008565141, -0.012041815, -0.033292875, -0.031266093, -0.02874347)); + result += mul(max(b, 0), float4x3(0.08709062, 0.09760889, 0.08988583, -0.09099671, -0.102120616, -0.098076016, 0.057814583, 0.06999608, 0.05961344, 0.12246188, 0.1319784, 0.12254915)); + result += mul(max(c, 0), float4x3(0.07694916, 0.0822054, 0.07549296, -0.046808865, -0.051509347, -0.035890795, 0.01599848, 0.014677793, 0.0086143715, 0.033142705, 0.0426565, 0.035911378)); + result += mul(max(d, 0), float4x3(-0.0008269902, 0.0009082343, 0.014101725, 0.0006387551, 0.005079344, -0.013034868, 0.013909732, 0.011026747, 0.012485332, 0.027028518, 0.022164145, 0.03183532)); + result += mul(max(e, 0), float4x3(-0.33575395, -0.36700967, -0.34140685, 0.35850254, 0.37535715, 0.34613726, -0.12680013, -0.1256115, -0.112494245, -0.061541136, -0.059120018, -0.06552594)); + result += mul(max(f, 0), float4x3(-0.047570463, -0.050335366, -0.04665491, -0.110970475, -0.12363716, -0.11072252, 0.041563414, 0.059771337, 0.045290247, -0.17999935, -0.19700716, -0.17459513)); + result += mul(max(g, 0), float4x3(0.078488424, 0.07483357, 0.08347933, -0.0063715233, 0.00035415235, -0.010886946, 0.031237155, 0.02512343, 0.034399323, -0.023146842, -0.026732154, -0.027644241)); + result += mul(max(h, 0), float4x3(-0.05906883, -0.06784104, -0.04506148, -0.003939601, -0.0011749315, -0.006256036, -0.1662408, -0.16871658, -0.16598499, 0.051277652, 0.04837499, 0.05120855)); + result += mul(max(i, 0), float4x3(0.08158806, 0.08674548, 0.07437206, -0.05765347, -0.06196418, -0.057311118, 0.26747537, 0.2668808, 0.2389857, -0.010376844, -0.01690028, -0.008414153)); + result += mul(max(-a, 0), float4x3(0.030539425, 0.02415435, 0.039969034, 0.006491679, 0.014436586, 0.005435709, -0.0058292216, -0.013982021, -0.011243379, 0.025942149, 0.015361476, 0.019134998)); + result += mul(max(-b, 0), float4x3(-0.06322247, -0.07146787, -0.06673042, 0.028702464, 0.039047733, 0.039646607, -0.072553575, -0.08046175, -0.07027197, -0.1447189, -0.1539398, -0.1466465)); + result += mul(max(-c, 0), float4x3(-0.046430312, -0.054549117, -0.048076343, 0.032971155, 0.02980819, 0.029172963, -0.017612953, -0.015100736, -0.01202649, -0.026717246, -0.028401854, -0.034548033)); + result += mul(max(-d, 0), float4x3(-0.0020459262, -0.0008748501, -0.012601956, 0.0054226154, 0.008867029, 0.018921215, -0.0021330053, -0.0036601655, -0.0022091097, -0.08636891, -0.10203159, -0.09741449)); + result += mul(max(-e, 0), float4x3(0.07306159, 0.08245483, 0.06548199, -0.1933229, -0.20326294, -0.19189309, 0.107496604, 0.11584994, 0.10907522, 0.30877885, 0.31297725, 0.30890995)); + result += mul(max(-f, 0), float4x3(0.03192904, 0.035112645, 0.033732817, 0.074100636, 0.08349646, 0.06659352, -0.1136165, -0.12470947, -0.11192198, 0.14465587, 0.16328491, 0.13984151)); + result += mul(max(-g, 0), float4x3(-0.05098033, -0.053096622, -0.05533725, 0.0045651463, -0.007682458, 0.0026934785, -0.021199327, -0.016210148, -0.030939564, -0.031621892, -0.046702545, -0.02647333)); + result += mul(max(-h, 0), float4x3(0.055801813, 0.06430485, 0.05052402, 0.0241233, 0.013879883, 0.017344628, 0.08707151, 0.10031039, 0.095042154, -0.109053336, -0.11414017, -0.111838564)); + result += mul(max(-i, 0), float4x3(0.030582374, 0.03604719, 0.040417343, 0.038665913, 0.036998056, 0.030004544, 0.09209076, 0.10010001, 0.08389406, -0.014655714, -0.0074866647, -0.012227013)); + result += float3(-0.008303841, -0.008251826, -0.0069884053); + + result += INPUT.SampleLevel(sam, pos, 0).rgb; + + WriteToOutput(gxy, result); +} diff --git a/src/Effects/Anime4K/Anime4K_Restore_Soft_UL.hlsl b/src/Effects/Anime4K/Anime4K_Restore_Soft_UL.hlsl index 88982a215..0e9cb52b2 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_Soft_UL.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_Soft_UL.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_Soft_3 +//!SORT_NAME Anime4K_Restore_Soft_4 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_Soft_VL.hlsl b/src/Effects/Anime4K/Anime4K_Restore_Soft_VL.hlsl index 113453ced..c74bf7a64 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_Soft_VL.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_Soft_VL.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_Soft_2 +//!SORT_NAME Anime4K_Restore_Soft_3 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_UL.hlsl b/src/Effects/Anime4K/Anime4K_Restore_UL.hlsl index 3e12a7feb..56649a0e5 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_UL.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_UL.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_3 +//!SORT_NAME Anime4K_Restore_4 //!TEXTURE diff --git a/src/Effects/Anime4K/Anime4K_Restore_VL.hlsl b/src/Effects/Anime4K/Anime4K_Restore_VL.hlsl index 4109710a9..13c76d1c5 100644 --- a/src/Effects/Anime4K/Anime4K_Restore_VL.hlsl +++ b/src/Effects/Anime4K/Anime4K_Restore_VL.hlsl @@ -5,7 +5,7 @@ //!VERSION 3 //!OUTPUT_WIDTH INPUT_WIDTH //!OUTPUT_HEIGHT INPUT_HEIGHT -//!SORT_NAME Anime4K_Restore_2 +//!SORT_NAME Anime4K_Restore_3 //!TEXTURE diff --git a/src/Effects/Effects.vcxproj b/src/Effects/Effects.vcxproj index fa2613e3e..c2c7ebae6 100644 --- a/src/Effects/Effects.vcxproj +++ b/src/Effects/Effects.vcxproj @@ -141,6 +141,12 @@ Document + + Document + + + Document + Document diff --git a/src/Effects/Effects.vcxproj.filters b/src/Effects/Effects.vcxproj.filters index 003398507..756d193e8 100644 --- a/src/Effects/Effects.vcxproj.filters +++ b/src/Effects/Effects.vcxproj.filters @@ -75,6 +75,12 @@ Anime4K + + Anime4K + + + Anime4K + Anime4K diff --git a/src/Updater/PackageFiles.h b/src/Updater/PackageFiles.h index f8dd035c1..3e7c38d64 100644 --- a/src/Updater/PackageFiles.h +++ b/src/Updater/PackageFiles.h @@ -116,6 +116,8 @@ static constexpr const wchar_t* V0_10_3_FILES[] = { L"effects\\Anime4K\\Anime4K_Restore_Soft_VL.hlsl", L"effects\\Anime4K\\Anime4K_Restore_UL.hlsl", L"effects\\Anime4K\\Anime4K_Restore_VL.hlsl", + L"effects\\Anime4K\\Anime4K_Restore_S.hlsl", + L"effects\\Anime4K\\Anime4K_Restore_Soft_S.hlsl", L"effects\\Anime4K\\Anime4K_Thin_HQ.hlsl", L"effects\\Anime4K\\Anime4K_Upscale_Denoise_L.hlsl", L"effects\\Anime4K\\Anime4K_Upscale_Denoise_S.hlsl", From 3b76d0c9c6d4d94ea64c2a966532c90037130030 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Wed, 2 Aug 2023 09:51:52 +0800 Subject: [PATCH 16/70] docs: add IsaiasYang as a contributor for code (#694) * docs: update README.md [skip ci] * docs: update README_ZH.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 1 + README_ZH.md | 1 + 3 files changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 283f83604..2acc24b4b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -220,6 +220,15 @@ "contributions": [ "translation" ] + }, + { + "login": "IsaiasYang", + "name": "攸羚", + "avatar_url": "https://avatars.githubusercontent.com/u/20205571?v=4", + "profile": "https://github.com/IsaiasYang", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 075d2a57a..04e3cd425 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ Thanks go to these wonderful people: Zoommod
Zoommod

🌍 fil08
fil08

🌍 + 攸羚
攸羚

💻 diff --git a/README_ZH.md b/README_ZH.md index db5322996..be1c3e82a 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -110,6 +110,7 @@ Magpie 是一个轻量级的窗口缩放工具,内置了多种高效的缩放 Zoommod
Zoommod

🌍 fil08
fil08

🌍 + 攸羚
攸羚

💻 From c894baff5407211c9aaf5489f4a41e099b6fe1c8 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 5 Aug 2023 13:59:25 +0200 Subject: [PATCH 17/70] Translated using Weblate (Korean) (#696) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ko/ Co-authored-by: a6e5aa12f60f4a7a --- src/Magpie.App/Resources.language-ko.resw | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Magpie.App/Resources.language-ko.resw b/src/Magpie.App/Resources.language-ko.resw index 90a306274..696273c71 100644 --- a/src/Magpie.App/Resources.language-ko.resw +++ b/src/Magpie.App/Resources.language-ko.resw @@ -779,4 +779,10 @@ 실행 파일 + + 스케일 하는 동안 렌더링 성능 모니터링 + + + 창이 포그라운드일 때만 스케일 + \ No newline at end of file From c6125caa3d02affd81a266c20267422fbff450f9 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 7 Aug 2023 03:43:50 +0200 Subject: [PATCH 18/70] Translated using Weblate (Russian) (#697) Currently translated at 100.0% (242 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ru/ Co-authored-by: Felix14_v2 --- src/Magpie.App/Resources.language-ru.resw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Magpie.App/Resources.language-ru.resw b/src/Magpie.App/Resources.language-ru.resw index 4b2dfb714..60eed46cb 100644 --- a/src/Magpie.App/Resources.language-ru.resw +++ b/src/Magpie.App/Resources.language-ru.resw @@ -280,7 +280,7 @@ Язык
- Умолчания Windows + Windows (по умолчанию) Переносной режим @@ -304,7 +304,7 @@ Тёмный - Умолчания Windows + Windows (по умолчанию) Светлый From 006c1f9f165123c26ed36d0d45e25847c813cc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 8 Oct 2023 21:21:09 +0800 Subject: [PATCH 19/70] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.App/Magpie.App.vcxproj | 12 ++++++------ src/Magpie.App/conanfile.txt | 4 ++-- src/Magpie.App/packages.config | 4 ++-- src/Magpie.Core/Magpie.Core.vcxproj | 14 +++++++------- src/Magpie.Core/conanfile.txt | 7 +++---- src/Magpie.Core/packages.config | 4 ++-- src/Magpie/Magpie.vcxproj | 12 ++++++------ src/Magpie/conanfile.txt | 4 ++-- src/Magpie/packages.config | 4 ++-- 9 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index f18c67573..b44602fee 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -1,6 +1,6 @@ - + true @@ -593,8 +593,8 @@ - - + + @@ -602,8 +602,8 @@ - - - + + + \ No newline at end of file diff --git a/src/Magpie.App/conanfile.txt b/src/Magpie.App/conanfile.txt index 2c14d3a01..097a58b82 100644 --- a/src/Magpie.App/conanfile.txt +++ b/src/Magpie.App/conanfile.txt @@ -1,6 +1,6 @@ [requires] -fmt/9.1.0 -spdlog/1.11.0 +fmt/10.1.1 +spdlog/1.12.0 parallel-hashmap/1.37 rapidjson/cci.20220822 kuba-zip/0.2.6 diff --git a/src/Magpie.App/packages.config b/src/Magpie.App/packages.config index b95621d37..5ca7a4dad 100644 --- a/src/Magpie.App/packages.config +++ b/src/Magpie.App/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/src/Magpie.Core/Magpie.Core.vcxproj b/src/Magpie.Core/Magpie.Core.vcxproj index c1e203618..96582e0f3 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj +++ b/src/Magpie.Core/Magpie.Core.vcxproj @@ -1,6 +1,6 @@ - + Debug @@ -145,23 +145,23 @@ - - - false + + + - + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - + + \ No newline at end of file diff --git a/src/Magpie.Core/conanfile.txt b/src/Magpie.Core/conanfile.txt index 91d9a0bda..bbaf0d6fb 100644 --- a/src/Magpie.Core/conanfile.txt +++ b/src/Magpie.Core/conanfile.txt @@ -1,10 +1,10 @@ [requires] -fmt/9.1.0 -spdlog/1.11.0 +fmt/10.1.1 +spdlog/1.12.0 parallel-hashmap/1.37 muparser/2.3.4 yas/7.1.0 -imgui/1.89.4 +imgui/1.89.9 [generators] visual_studio @@ -13,4 +13,3 @@ visual_studio fmt:header_only=True spdlog:header_only=True spdlog:no_exceptions=True - diff --git a/src/Magpie.Core/packages.config b/src/Magpie.Core/packages.config index cb22c8c8d..1b8cfbd96 100644 --- a/src/Magpie.Core/packages.config +++ b/src/Magpie.Core/packages.config @@ -1,4 +1,4 @@ - + - + \ No newline at end of file diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index c921aeadd..81a3d4c01 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -1,6 +1,6 @@ - + @@ -130,8 +130,8 @@ - - + + @@ -139,8 +139,8 @@ - - - + + + \ No newline at end of file diff --git a/src/Magpie/conanfile.txt b/src/Magpie/conanfile.txt index 26fceae9d..7859ae018 100644 --- a/src/Magpie/conanfile.txt +++ b/src/Magpie/conanfile.txt @@ -1,6 +1,6 @@ [requires] -fmt/9.1.0 -spdlog/1.11.0 +fmt/10.1.1 +spdlog/1.12.0 parallel-hashmap/1.37 [generators] diff --git a/src/Magpie/packages.config b/src/Magpie/packages.config index b95621d37..5ca7a4dad 100644 --- a/src/Magpie/packages.config +++ b/src/Magpie/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file From 2158c2bf38428e102f29ea763b2c11ee78946451 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 9 Oct 2023 05:29:18 +0200 Subject: [PATCH 20/70] Translations update from Hosted Weblate (#712) * Added translation using Weblate (German) * Translated using Weblate (German) Currently translated at 11.1% (27 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/de/ * Translated using Weblate (Indonesian) Currently translated at 84.2% (204 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/id/ * Added translation using Weblate (Hungarian) * Translated using Weblate (Hungarian) Currently translated at 34.7% (84 of 242 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/hu/ --------- Co-authored-by: she hash Co-authored-by: Reza Almanda Co-authored-by: Zan 1456 --- src/Magpie.App/Resources.language-de.resw | 145 ++++++++++ src/Magpie.App/Resources.language-hu.resw | 314 ++++++++++++++++++++++ src/Magpie.App/Resources.language-id.resw | 48 ++++ 3 files changed, 507 insertions(+) create mode 100644 src/Magpie.App/Resources.language-de.resw create mode 100644 src/Magpie.App/Resources.language-hu.resw diff --git a/src/Magpie.App/Resources.language-de.resw b/src/Magpie.App/Resources.language-de.resw new file mode 100644 index 000000000..a81f28085 --- /dev/null +++ b/src/Magpie.App/Resources.language-de.resw @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Aktivierung + + + Über + + + Aktivieren + + + Jetziges Fenster + + + Startseite + + + Säubern + + + Fenster im Vordergrund skalieren, sobald der Timer ended + + + Automatisch skalieren, sobald das Fenster zum Vordergrund zurück kehrt. + + + Verspätetes skalieren + + + Abbrechen + + + Drücke eine Tastenkombination, um die Verknüpfung zu verändern + + + Speichern + + + Über + + + Startseite + + + Erstellen + + + Name + + + Ungültige Verknüpfung + + + Neues Profil + + + Neues Profil + + + Nur Verknüpfungen, die mit Windows Key, Ctrl, Alt oder Shift starten, sind gültig. + + + Abbrechen + + + Wähle ein Fenster + + + Öffne ein Fenster, um ein Profil zu erstellen + + + Profile + + + Aus + + + An + + + Skalierungs Konfiguration + + + Hell + + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-hu.resw b/src/Magpie.App/Resources.language-hu.resw new file mode 100644 index 000000000..61cd94730 --- /dev/null +++ b/src/Magpie.App/Resources.language-hu.resw @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Aktiválás + + + Haladó + + + Github tároló + + + Ki + + + Rólunk + + + Rendszerrel megegyező + + + Mégsem + + + Végrehajtható fájl + + + A konfigurációs fájl nem érvényes JSON + + + Kilépés + + + Automatikus visszaállítás + + + Kiadási megjegyzések + + + Skálázás {}mp után + + + Hiba jelentése + + + JSON Fájl + + + Konfigurációs fájl helye: +{} + + + Létrehozás + + + Időzítések + + + Aktiválás + + + Sötét + + + Verzió + + + Egyéni + + + Törlés + + + Kezdőlap + + + Folytatás + + + Funkció kérése + + + Jelenlegi ablak: + + + A cím üres + + + Nincs + + + Egyéb linkek + + + A konfigurációs fájl elemzése nem sikerült + + + Kezdőlap + + + Téma + + + Kilépés + + + Letöltés és telepítés + + + Ablak kiválasztása + + + Nyelv + + + Importálás + + + Automatikus méretezés, amikor az ablak visszatér az előtérbe + + + Alapértelmezettek + + + Verzió + + + Késleltetett méretezés + + + Rólunk + + + Késleltetés másodpercben + + + Mentés + + + Bal + + + Világos + + + Név + + + Átnevezés + + + {} elérhető + + + Már használatban + + + Érvénytelen parancsikon + + + Letöltés meghiúsult + + + Mégsem + + + Hozzájárulási iránymutatások + + + Frissítések keresése... + + + Telepítés + + + Be + + + Licenc + + + Ürítés + + + Az előtérben lévő ablak méretezése az időzítő lejártakor + + + Új profil + + + Beszélgetések + + + Kitöltés + + + Név + + + Frissítések keresése + + + Próbáld újra + + + Hiba + + + Másolás innen + + + Frissítések automatikus keresése + + + Magpie naprakész + + + Mégse + + + Visszajelzés + + + Újrarendezés + + + Folytatás + + + Kísérleti frissítések keresése + + + Nyomja meg a billentyűkombinációt a parancsikon megváltoztatásához + + + Megjelenési megjegyzések + + + GYIK + + + Figyelmeztetés + + + Beállítások frissítése + + + Méretarány + + + Letöltés + + + A frissítések ellenőrzése nem sikerült, kérjük, próbálja meg később újra + + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-id.resw b/src/Magpie.App/Resources.language-id.resw index b687caa65..68ec00be5 100644 --- a/src/Magpie.App/Resources.language-id.resw +++ b/src/Magpie.App/Resources.language-id.resw @@ -622,4 +622,52 @@ Anda harus mengaktifkan "Tampilkan aplikasi pada system tray" untuk menggunakan pengaturan ini + + Pengaturan ini hanya untuk penggunaan pengembangan + + + Meminimalkan ke baki sistem di startup + + + Keluar + + + Nonaktifkan cache efek + + + Simpan kode sumber ketika efek parsing + + + Lanjutkan + + + Aktifkan mode portabel + + + Mode debug + + + Keluar + + + File konfigurasi lokal berasal dari versi yang tidak dikenal dan mungkin tidak diuraikan dengan benar. + + + Pilihan pengembang + + + Perlakukan peringatan sebagai eror saat menyusun efek + + + Eror + + + Lanjutkan + + + Peringatan + + + File konfigurasi global berasal dari versi yang tidak dikenal dan mungkin tidak diuraikan dengan benar. + \ No newline at end of file From 0fda637065c134a4cba96cab8d60a0bdd66877ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Mon, 9 Oct 2023 21:55:18 +0800 Subject: [PATCH 21/70] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E6=B8=85?= =?UTF-8?q?=E5=8D=95=E6=96=87=E4=BB=B6=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.App/App.cpp | 6 ------ src/Magpie.App/CaptionButtonsControl.idl | 1 - src/Magpie/app.manifest | 22 ++++++++++++++-------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Magpie.App/App.cpp b/src/Magpie.App/App.cpp index e9ef56d2a..ed8ecd901 100644 --- a/src/Magpie.App/App.cpp +++ b/src/Magpie.App/App.cpp @@ -50,12 +50,6 @@ App::App() { } LocalizationService::Get().EarlyInitialize(); - - // 根据操作系统选择图标字体 - Resources().Insert( - box_value(L"SymbolThemeFontFamily"), - FontFamily(isWin11 ? L"Segoe Fluent Icons" : L"Segoe MDL2 Assets") - ); } App::~App() { diff --git a/src/Magpie.App/CaptionButtonsControl.idl b/src/Magpie.App/CaptionButtonsControl.idl index ccc90ed69..e3e14de69 100644 --- a/src/Magpie.App/CaptionButtonsControl.idl +++ b/src/Magpie.App/CaptionButtonsControl.idl @@ -1,5 +1,4 @@ namespace Magpie.App { - // 为简单起见,确保这些值与 WM_NCHITTEST 所使用的值相同 enum CaptionButton { Minimize = 8, // HTMINBUTTON Maximize = 9, // HTMAXBUTTON diff --git a/src/Magpie/app.manifest b/src/Magpie/app.manifest index 36416dfef..d58a747ec 100644 --- a/src/Magpie/app.manifest +++ b/src/Magpie/app.manifest @@ -13,27 +13,33 @@ - - + + + + + + - + - - - + true + PerMonitorV2 + SegmentHeap - + - + + + Date: Mon, 9 Oct 2023 22:16:31 +0800 Subject: [PATCH 22/70] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=9C=AA?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=9A=84=E7=BF=BB=E8=AF=91=20=E5=8D=B3?= =?UTF-8?q?=E4=BD=BF=E6=9C=AA=E5=AE=8C=E6=88=90=E4=B9=9F=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E4=BE=9B=E7=94=A8=E6=88=B7=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie.App/LocalizationService.cpp | 4 ++++ src/Magpie.App/Magpie.App.vcxproj | 4 ++++ src/Magpie.App/Magpie.App.vcxproj.filters | 12 ++++++++++++ src/Magpie.Core/ImGuiHelper.h | 4 ++-- src/Magpie.Core/OverlayDrawer.cpp | 4 ++-- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Magpie.App/LocalizationService.cpp b/src/Magpie.App/LocalizationService.cpp index 5e5786a33..53ae714af 100644 --- a/src/Magpie.App/LocalizationService.cpp +++ b/src/Magpie.App/LocalizationService.cpp @@ -11,8 +11,12 @@ namespace winrt::Magpie::App { // 标签必须为小写 static std::array SUPPORTED_LANGUAGES{ + L"de", L"en-us", L"es", + L"fr", + L"hu", + L"id", L"it", L"ja", L"ko", diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index b44602fee..2c0800a97 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -573,8 +573,12 @@ + + + + diff --git a/src/Magpie.App/Magpie.App.vcxproj.filters b/src/Magpie.App/Magpie.App.vcxproj.filters index c6951dea6..8d8b1b869 100644 --- a/src/Magpie.App/Magpie.App.vcxproj.filters +++ b/src/Magpie.App/Magpie.App.vcxproj.filters @@ -297,6 +297,18 @@ Strings + + Strings + + + Strings + + + Strings + + + Strings + diff --git a/src/Magpie.Core/ImGuiHelper.h b/src/Magpie.Core/ImGuiHelper.h index e560d5235..d485189bf 100644 --- a/src/Magpie.Core/ImGuiHelper.h +++ b/src/Magpie.Core/ImGuiHelper.h @@ -11,9 +11,9 @@ struct ImGuiHelper { static constexpr ImWchar NOT_NUMBER_RANGES[] = { 0x20, L'0' - 1, L'9' + 1, 0x7E, 0 }; // Basic Latin static constexpr ImWchar ENGLISH_RANGES[] = { 0x20, 0x7E, 0 }; - // Basic Latin + Latin-1 Supplement + Latin Extended-A + // Basic Latin + Latin-1 Supplement + Latin Extended-A,用于土耳其语、匈牙利语等 // 参见 https://en.wikipedia.org/wiki/Latin_Extended-A - static constexpr ImWchar TURKISH_RANGES[] = { 0x20, 0x17F, 0 }; + static constexpr ImWchar Latin_1_Extended_A_RANGES[] = { 0x20, 0x17F, 0 }; }; } diff --git a/src/Magpie.Core/OverlayDrawer.cpp b/src/Magpie.Core/OverlayDrawer.cpp index 7c390bc1a..5920481c5 100644 --- a/src/Magpie.Core/OverlayDrawer.cpp +++ b/src/Magpie.Core/OverlayDrawer.cpp @@ -355,8 +355,8 @@ void OverlayDrawer::_BuildFontUI(std::wstring_view language, const std::vector Date: Mon, 9 Oct 2023 22:25:58 +0800 Subject: [PATCH 23/70] =?UTF-8?q?chore:=20=E5=88=A0=E9=99=A4=E6=8D=90?= =?UTF-8?q?=E8=B5=A0=E6=B8=A0=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/FUNDING.yml | 13 ------------- FUNDING.md | 9 --------- "img/\350\265\236\350\265\217\347\240\201.png" | Bin 78931 -> 0 bytes 3 files changed, 22 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 FUNDING.md delete mode 100644 "img/\350\265\236\350\265\217\347\240\201.png" diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 738671c0c..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,13 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -custom: ['https://github.com/Blinue/Magpie/blob/main/FUNDING.md'] diff --git a/FUNDING.md b/FUNDING.md deleted file mode 100644 index 86207bac4..000000000 --- a/FUNDING.md +++ /dev/null @@ -1,9 +0,0 @@ -捐助可以让我更专注于开源项目的开发和维护。感谢你的支持! - -赞赏码 - -赞赏码 - -Or - -Buy Me A Coffee diff --git "a/img/\350\265\236\350\265\217\347\240\201.png" "b/img/\350\265\236\350\265\217\347\240\201.png" deleted file mode 100644 index 59d8f6aaa196d9c8a67392bbab15235ef99c9ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 78931 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%0Dec}PVaI|X_P6_ecRy+L3K44>N@eiO*V3jT~ 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 From 97c00e2cf2a2affd4ef667a2bf853d9d64756eef Mon Sep 17 00:00:00 2001 From: OHaiiBuzzle <23693150+ohaiibuzzle@users.noreply.github.com> Date: Tue, 10 Oct 2023 15:55:31 +0700 Subject: [PATCH 24/70] feat: Vietnamese Localizations (#725) * feat: Vietnamese Localizations * fix: adding updated strings * fix: remove SubType Designer from vcxproj (what, how and why) * fix: undo auto-formatting in vcxproj.filters * fix: added Vietnamese font glyphs for Overlay --- src/Magpie.App/LocalizationService.cpp | 1 + src/Magpie.App/Magpie.App.vcxproj | 1 + src/Magpie.App/Magpie.App.vcxproj.filters | 3 + src/Magpie.App/Resources.language-vi.resw | 847 ++++++++++++++++++++++ src/Magpie.Core/OverlayDrawer.cpp | 2 + 5 files changed, 854 insertions(+) create mode 100644 src/Magpie.App/Resources.language-vi.resw diff --git a/src/Magpie.App/LocalizationService.cpp b/src/Magpie.App/LocalizationService.cpp index 53ae714af..0675bb27f 100644 --- a/src/Magpie.App/LocalizationService.cpp +++ b/src/Magpie.App/LocalizationService.cpp @@ -24,6 +24,7 @@ static std::array SUPPORTED_LANGUAGES{ L"ru", L"tr", L"uk", + L"vi", L"zh-hans", L"zh-hant" }; diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index 2c0800a97..d960278b9 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -588,6 +588,7 @@ + diff --git a/src/Magpie.App/Magpie.App.vcxproj.filters b/src/Magpie.App/Magpie.App.vcxproj.filters index 8d8b1b869..08554d9ca 100644 --- a/src/Magpie.App/Magpie.App.vcxproj.filters +++ b/src/Magpie.App/Magpie.App.vcxproj.filters @@ -309,6 +309,9 @@ Strings + + Strings + diff --git a/src/Magpie.App/Resources.language-vi.resw b/src/Magpie.App/Resources.language-vi.resw new file mode 100644 index 000000000..e23fa6328 --- /dev/null +++ b/src/Magpie.App/Resources.language-vi.resw @@ -0,0 +1,847 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Phản hồi + + + Diễn đàn + + + Báo lỗi + + + Yêu cầu tính năng + + + Các liên kết khác + + + Hướng dẫn đóng góp + + + FAQ + + + Bản quyền + + + Repo GitHub + + + Giới thiệu + + + Phiên bản + + + Kiểm tra cập nhật + + + Kiểm tra cập nhật thất bại, vui lòng thử lại sau + + + Đang kiểm tra cập nhật + + + Hủy + + + Tải và cài đặt + + + Nội dung cập nhật + + + Thử lại + + + Đã có bản cập nhật {} + + + Cài đặt cập nhật + + + Kiểm tra cập nhật tự động + + + Kiểm tra các cập nhật thử nghiệm + + + Magpie đã được cập nhật + + + Tải xuống thất bại + + + Đang tải xuống + + + Đang cài đặt + + + Phiên bản + + + Lỗi + + + Thoát + + + Cảnh báo + + + Vị trí file cấu hình: +{} + + + File cấu hình không phải JSON hợp lệ + + + Không thể phân giải file cấu hình + + + Không thể đọc file cấu hình + + + File cấu hình của một phiên bản không xác định và có thể không được phân giải đúng + + + Tiếp tục + + + Thoát + + + File cấu hình của một phiên bản không xác định và có thể không được phân giải đúng + + + Tiếp tục + + + Bật chế độ portable + + + Xuất các chế độ Scale + + + File chạy + + + File JSON + + + Kích hoạt + + + Tự động scale cửa sổ trên cùng + + + Tự động scale + + + Kích hoạt + + + Xóa + + + Cửa sổ hiện tại: + + + Tiêu đề trống + + + Chính + + + Phím tắt + + + Overlay trong ứng dụng + + + Phím tắt overlay + + + Scale + + + Phím tắt Scale + + + Scale cửa sổ trên cùng khi hết thời gian + + + Thời gian chờ Scale + + + Scale sau {} giây + + + Hủy + + + Thời gian bằng giây + + + Kiểm tra cập nhật tự động + + + Tải và cài đặt + + + Nội dung cập nhật + + + Nhắc tôi sau + + + Đã có bản cập nhật {} + + + Nhập các chế độ Scale + + + Nhập file ScaleModels.json + + + Giới thiệu + + + Mặc định + + + Chính + + + Cấu hình mới + + + Chọn một cửa sổ + + + Chép từ + + + Tạo + + + Tên + + + Mở một cửa sổ mới để tạo cấu hình + + + Cấu hình mới + + + Cấu hình + + + Cài đặt Scaling + + + Khóa + + + Độ phủ mờ + + + Mở khóa + + + Profiler + + + Phương pháp lấy cửa sổ + + + Thông tin khung hình + + + Chuyển sang tốc độ khung hình + + + Chuyển sang thời gian khung hình + + + Timing + + + Chuyển sang hiệu ứng + + + Chuyển sang render pass + + + Tổng cộng + + + VSync + + + Nâng cao + + + Tắt DirectFlip + + + Thông số khởi chạy + + + Sửa + + + Con trỏ chuột + + + Vẽ con trỏ chuột + + + Thay đổi tốc độ con trỏ khi scale + + + Thuật toán + + + Bilinear + + + Nearest-neighbor + + + Mức độ Scale + + + Tùy chỉnh + + + Không Scale + + + Như cửa sổ gốc + + + Chung + + + Chế độ game 3D + + + Tự động scale cửa sổ trên cùng + + + Phương pháp lấy cửa sổ + + + Mặc định + + + Màn hình ưu tiên + + + Tất cả màn hình + + + Màn hình gần cửa sổ gốc nhất + + + Màn hình hiển thị cửa sổ gốc + + + Chế độ Scale + + + Không + + + Chạy + + + Tùy chọn + + + Thay đổi file chạy + + + Xóa + + + Xóa + + + Bạn có chắc chán muốn xóa cấu hình này? + + + Mở vị trí chương trình + + + Đổi tên + + + OK + + + Đổi tên + + + Đổi thứ tự + + + Xuống + + + Lên + + + Đổi thứ tự + + + Hiệu năng + + + Card đồ họa + + + Hiển thị bộ đếm FPS + + + VSync + + + Thêm độ trễ để cải thiện hiệu năng + + + Cửa sổ nguồn + + + Chỉ sử dụng được với Graphics Capture và Desktop Duplication + + + Lấy cả thanh tiêu đề + + + Lề cửa sổ tùy chỉnh + + + Dưới + + + Trái + + + px + + + Phải + + + Trên + + + Vô hiệu hóa thay đổi cỡ cửa sổ + + + Chung + + + Được sử dụng khi kích thước hình ảnh lớn hơn màn hình + + + Chế độ downscale mặc định + + + Không + + + Xuất + + + Nhập + + + Nhập file ScaleModels.json + + + Tùy chọn + + + Cài đặt Scaling + + + Thông số + + + Phân giải thất bại + + + Các chế độ scale + + + Thêm hiệu ứng + + + Xóa + + + Xóa + + + Hiệu ứng này đang được sử dụng bởi: + + + Bạn có chắc chắn muốn xóa hiệu ứng này? + + + Hiệu ứng không xác định + + + Không thể kéo thả khi đang chạy dưới quyền quản trị + + + Kéo thả để thay đổi thứ tự + + + Một số hiệu ứng không thể được phân giải + + + Tùy chọn + + + Xóa + + + Xuống + + + Lên + + + Xuống + + + Lên + + + Chế độ scale mới + + + Chép từ + + + Không + + + Tạo + + + Tên + + + Chế độ scale mới + + + Đổi tên + + + OK + + + Đổi tên + + + Scale + + + Chiều cao (theo tỷ lệ scale) + + + Chiều cao (theo pixel) + + + Loại + + + Tuyệt đối + + + Đặt kích cỡ sau scale + + + Tỷ lệ scale + + + Đặt tỷ lệ tương đối với hình ảnh gốc + + + Vừa màn hình + + + Hiển thị đầy màn hình, hình ảnh có thể bị méo + + + Giữ tỷ lệ + + + Giữ tỷ lệ hình ảnh sau khi làm đầy màn hình + + + Chiều rông (theo tỷ lệ) + + + Chiều rộng (theo pixel) + + + Chọn file chạy của chương trình + + + Nâng cao + + + Cho phép scale cửa sổ toàn màn hình + + + Cải thiện hiệu năng. Tuy nhiên các hiệu ứng phải được biên dịch lại khi các thông số của chúng đươc chỉnh + + + Đặt thông số hiệu ứng trực tiếp + + + Các thông báo và pop-up từ một số ứng dụng sẽ bị chặn + + + Giả lập chế độ toàn màn hình độc lập + + + Những cài đặt này chỉ dành cho mục đích phát triển + + + Cài đặt nhà phát triển + + + Chế độ gỡ lỗi + + + Tắt cache hiệu ứng + + + Tắt cache phông chữ + + + Lưu mã nguồn khi đọc hiệu ứng + + + Đặt cảnh bảo như lỗi khi đọc hiệu ứng + + + Chung + + + Ngôn ngữ + + + Mặc định Windows + + + Chế độ Portable + + + Mở vị trí file cấu hình + + + Cần khởi động lại Magpie để thiết lập cấu hình + + + Khởi động lại Magpie + + + Magpie sẽ tiếp tục chạy kể cả khi cửa sổ chính bị đóng + + + Hiển thị trên thanh tác vụ + + + Màu + + + Tối + + + Sáng + + + Mặc định Windows + + + Chạy + + + Bạn cần mở với quyền quản trị viên để thay đổi cài đặt này + + + Luôn chạy với quyền quản trị viên + + + Chạy khi khởi động + + + Bạn cần bật "Hiển thị trên thanh tác vụ" để sử dụng cài đặt này + + + Thu nhỏ về thanh tác vụ khi khởi động + + + Hủy + + + Nhấn một tổ hợp phím để đổi phím tắt này + + + Đã được sử dụng + + + Phím tắt không hợp lệ + + + Lưu + + + Chỉ các phím tắt sử dụng phim Windows, Ctrl, Alt và Shift là hợp lệ + + + Tắt + + + Bật + + + Thoát + + + Cửa sổ chính + + + Theo dõi hiệu năng render trong khi scale + + + Scale cửa sổ trên cùng + + \ No newline at end of file diff --git a/src/Magpie.Core/OverlayDrawer.cpp b/src/Magpie.Core/OverlayDrawer.cpp index 5920481c5..04cf70783 100644 --- a/src/Magpie.Core/OverlayDrawer.cpp +++ b/src/Magpie.Core/OverlayDrawer.cpp @@ -357,6 +357,8 @@ void OverlayDrawer::_BuildFontUI(std::wstring_view language, const std::vector Date: Tue, 10 Oct 2023 16:57:49 +0800 Subject: [PATCH 25/70] docs: add ohaiibuzzle as a contributor for translation (#726) * docs: update README.md [skip ci] * docs: update README_ZH.md [skip ci] * docs: update .all-contributorsrc [skip ci] --------- Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- .all-contributorsrc | 9 +++++++++ README.md | 1 + README_ZH.md | 1 + 3 files changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 2acc24b4b..b684dae02 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -229,6 +229,15 @@ "contributions": [ "code" ] + }, + { + "login": "ohaiibuzzle", + "name": "OHaiiBuzzle", + "avatar_url": "https://avatars.githubusercontent.com/u/23693150?v=4", + "profile": "http://ohaiibuzzle.dev", + "contributions": [ + "translation" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 04e3cd425..d6a00300d 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,7 @@ Thanks go to these wonderful people: Zoommod
Zoommod

🌍 fil08
fil08

🌍 攸羚
攸羚

💻 + OHaiiBuzzle
OHaiiBuzzle

🌍 diff --git a/README_ZH.md b/README_ZH.md index be1c3e82a..2a42fe225 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -111,6 +111,7 @@ Magpie 是一个轻量级的窗口缩放工具,内置了多种高效的缩放 Zoommod
Zoommod

🌍 fil08
fil08

🌍 攸羚
攸羚

💻 + OHaiiBuzzle
OHaiiBuzzle

🌍 From 0b58d65405d65a3cc19c596dd16b1a694832557e Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Wed, 11 Oct 2023 14:27:42 +0800 Subject: [PATCH 26/70] =?UTF-8?q?=E4=BF=AE=E5=89=AA=20resources.pri=20(#72?= =?UTF-8?q?7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 实现修剪 resources.pri,并将发布脚本移植为 python * chore: 编译过程中添加两个消息 * chore: 更新工作流的触发条件 * chore: 修复中文字符显示 不知为何 python 的 stdout 的编码默认为 ANSI,而不是 UTF-8 --- .github/workflows/build.yml | 9 +- .github/workflows/wiki.yml | 2 +- .gitignore | 3 +- Directory.Build.props | 1 + ci/build.ps1 | 29 ------ publish.py | 201 ++++++++++++++++++++++++++++++++++++ 6 files changed, 208 insertions(+), 37 deletions(-) delete mode 100644 ci/build.ps1 create mode 100644 publish.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e33a972d7..f36073b42 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,9 +2,9 @@ name: build on: push: - paths: [ 'Magpie.sln', 'src/**', 'ci/**', '.github/workflows/build.yml' ] + paths: [ '.github/workflows/build.yml', 'Magpie.sln', '*.props', 'publish.py', 'src/**' ] pull_request: - paths: [ 'Magpie.sln', 'src/**', 'ci/**', '.github/workflows/build.yml' ] + paths: [ '.github/workflows/build.yml', 'Magpie.sln', '*.props', 'publish.py', 'src/**' ] # env: # Configuration type to build. @@ -31,11 +31,8 @@ jobs: - name: Setup Conan run: pip install conan<2.0 - - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1 - - name: Build - run: pwsh "ci/build.ps1" + run: python "publish.py" - name: Save hash id: hash diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml index 75c329a3e..1d3d61a75 100644 --- a/.github/workflows/wiki.yml +++ b/.github/workflows/wiki.yml @@ -5,7 +5,7 @@ on: # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ main ] - paths: [ 'docs/**' ] + paths: [ '.github/workflows/wiki.yml', 'docs/**', 'ci/wiki.sh' ] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: diff --git a/.gitignore b/.gitignore index 8b6d0fa54..3a17bb0d0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,14 @@ ## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +my_*/ + # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates -my_*/ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs diff --git a/Directory.Build.props b/Directory.Build.props index f800a05ef..91511cd1b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -18,6 +18,7 @@ + %(AdditionalOptions) /await:strict /utf-8 /Zc:__cplusplus /volatile:iso /fp:contract diff --git a/ci/build.ps1 b/ci/build.ps1 deleted file mode 100644 index ed74a4042..000000000 --- a/ci/build.ps1 +++ /dev/null @@ -1,29 +0,0 @@ -# 出错时终止 CI -$ErrorActionPreference = "Stop" - -msbuild /p:Configuration=Release`;Platform=x64 src\CONAN_INSTALL -if ($LastExitCode -ne 0) { - throw '编译 CONAN_INSTALL 失败' -} -msbuild /p:Configuration=Release`;Platform=x64`;OutDir=..\..\publish\ src\Effects -if ($LastExitCode -ne 0) { - throw '编译 Effects 失败' -} -msbuild /p:Configuration=Release`;Platform=x64`;OutDir=..\..\publish\ src\Magpie.Core -if ($LastExitCode -ne 0) { - throw '编译 Magpie.Core 失败' -} -msbuild /m /p:Configuration=Release`;Platform=x64`;BuildProjectReferences=false`;OutDir=..\..\publish\ src\Magpie -if($LastExitCode -ne 0) { - throw '编译 Magpie 失败' -} -msbuild /p:Configuration=Release`;Platform=x64`;OutDir=..\..\publish\ src\Updater -if ($LastExitCode -ne 0) { - throw '编译 Updater 失败' -} - -# 清理不需要的文件 -Set-Location .\publish\ -Remove-Item @("*.pdb", "*.lib", "*.exp", "*.winmd", "*.xml", "*.xbf", "dummy.*", "Microsoft.Web.WebView2.Core.dll") -Remove-Item @("Microsoft.UI.Xaml", "Magpie.App") -Recurse -Remove-Item *.pri -Exclude resources.pri diff --git a/publish.py b/publish.py new file mode 100644 index 000000000..1f9f0711e --- /dev/null +++ b/publish.py @@ -0,0 +1,201 @@ +import ctypes, sys +from ctypes import windll, wintypes +import uuid +import subprocess +import os +import glob +import shutil +from xml.etree import ElementTree + +try: + # https://docs.github.com/en/actions/learn-github-actions/variables + if os.environ["GITHUB_ACTIONS"].lower() == "true": + # 不知为何在 Github Actions 中运行时默认编码为 ANSI,并且 print 需刷新流才能正常显示 + for stream in [sys.stdout, sys.stderr]: + stream.reconfigure(encoding='utf-8') +except: + pass + +##################################################################### +# +# 使用 vswhere 查找 msbuild +# +##################################################################### + +class FOLDERID: + ProgramFilesX86 = uuid.UUID('{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}') + +# 包装 SHGetKnownFolderPath,来自 https://gist.github.com/mkropat/7550097 +def get_known_folder_path(folderid): + class GUID(ctypes.Structure): + _fields_ = [ + ("Data1", wintypes.DWORD), + ("Data2", wintypes.WORD), + ("Data3", wintypes.WORD), + ("Data4", wintypes.BYTE * 8) + ] + + def __init__(self, uuid_): + ctypes.Structure.__init__(self) + self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid_.fields + for i in range(2, 8): + self.Data4[i] = rest>>(8 - i - 1)*8 & 0xff + + CoTaskMemFree = windll.ole32.CoTaskMemFree + CoTaskMemFree.restype = None + CoTaskMemFree.argtypes = [ctypes.c_void_p] + + SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath + SHGetKnownFolderPath.argtypes = [ + ctypes.POINTER(GUID), + wintypes.DWORD, + wintypes.HANDLE, + ctypes.POINTER(ctypes.c_wchar_p) + ] + + fid = GUID(folderid) + pPath = ctypes.c_wchar_p() + if SHGetKnownFolderPath(ctypes.byref(fid), 0, wintypes.HANDLE(0), ctypes.byref(pPath)) != 0: + raise FileNotFoundError() + path = pPath.value + CoTaskMemFree(pPath) + return path + +programFilesX86Path = get_known_folder_path(FOLDERID.ProgramFilesX86); + +vswherePath = programFilesX86Path + "\\Microsoft Visual Studio\\Installer\\vswhere.exe" +if not os.access(vswherePath, os.X_OK): + raise Exception("未找到 vswhere") + +process = subprocess.run(vswherePath + " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe", capture_output=True) +msbuildPath = str(process.stdout, encoding="utf-8").splitlines()[0] +if not os.access(msbuildPath, os.X_OK): + raise Exception("未找到 msbuild") + +##################################################################### +# +# 编译 +# +##################################################################### + +os.chdir(os.path.dirname(__file__)) + +if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL") != 0: + raise Exception("编译 CONAN_INSTALL 失败") + +if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects") != 0: + raise Exception("编译 Effects 失败") + +if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core") != 0: + raise Exception("编译 Magpie.Core 失败") + +if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie") != 0: + raise Exception("编译 Magpie 失败") + +if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater") != 0: + raise Exception("编译 Updater 失败") + +##################################################################### +# +# 清理不需要的文件 +# +##################################################################### + +os.chdir(os.getcwd() + "\\publish") + +# 删除文件,忽略错误 +def remove_file(file): + try: + os.remove(file) + except: + pass + +# 删除文件夹,忽略错误 +def remove_folder(folder): + try: + shutil.rmtree(folder) + except: + pass + +remove_file("Microsoft.Web.WebView2.Core.dll") + +for pattern in ["*.pdb", "*.lib", "*.exp", "*.winmd", "*.xml", "*.xbf", "dummy.*"]: + for file in glob.glob(pattern): + remove_file(file) + +for file in glob.glob("*.pri"): + if file != "resources.pri": + remove_file(file) + +for folder in ["Microsoft.UI.Xaml", "Magpie.App"]: + remove_folder(folder) + +print("清理完毕", flush=True) + +##################################################################### +# +# 修剪 resources.pri +# 参考自 https://github.com/microsoft/microsoft-ui-xaml/pull/4400 +# +##################################################################### + +# 取最新的 Windows SDK +windowsSdkDir = sorted(glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*"))[-1]; +makepriPath = windowsSdkDir + "\\x64\\makepri.exe" +if not os.access(makepriPath, os.X_OK): + raise Exception("未找到 makepri") + +# 将 resources.pri 的内容导出为 xml +if os.system("\"" + makepriPath + "\" dump /dt detailed /o") != 0: + raise Exception("dump 失败") + +xmlTree = ElementTree.parse("resources.pri.xml") + +# 在 xml 中删除冗余资源 +for resourceNode in xmlTree.getroot().findall("ResourceMap/ResourceMapSubtree/ResourceMapSubtree/ResourceMapSubtree/NamedResource"): + name = resourceNode.get("name") + + if not name.endswith(".xbf"): + continue + + # 我们仅需 19h1 和 21h1 的资源,分别用于 Win10 和 Win11 + for key in ["compact", "Compact", "v1", "rs2", "rs3", "rs4", "rs5"]: + if key in name: + # 将文件内容替换为一个空格(Base64 为 "IA==") + resourceNode.find("Candidate/Base64Value").text = "IA==" + break + +xmlTree.write("resources.pri.xml", encoding="utf-8") + +with open("priconfig.xml", "w", encoding="utf-8") as f: + print(""" + + + + + + + + + + + + + + + + + + + + + +""", file=f) + +# 将 xml 重新封装成 pri +os.system("\"" + makepriPath + "\" new /pr . /cf priconfig.xml /in Magpie.App /o") + +os.remove("resources.pri.xml") +os.remove("priconfig.xml") + +print("已修剪 resources.pri", flush=True) From 642f1ae2793d5e6e10fe46221edaab800f741fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Wed, 11 Oct 2023 22:05:53 +0800 Subject: [PATCH 27/70] =?UTF-8?q?refactor:=20=E7=AE=80=E5=8C=96=E5=92=8C?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=20publish.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish.py | 97 +++++++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 60 deletions(-) diff --git a/publish.py b/publish.py index 1f9f0711e..0d1f43030 100644 --- a/publish.py +++ b/publish.py @@ -1,8 +1,6 @@ -import ctypes, sys -from ctypes import windll, wintypes -import uuid -import subprocess +import sys import os +import subprocess import glob import shutil from xml.etree import ElementTree @@ -12,7 +10,7 @@ if os.environ["GITHUB_ACTIONS"].lower() == "true": # 不知为何在 Github Actions 中运行时默认编码为 ANSI,并且 print 需刷新流才能正常显示 for stream in [sys.stdout, sys.stderr]: - stream.reconfigure(encoding='utf-8') + stream.reconfigure(encoding="utf-8") except: pass @@ -22,52 +20,16 @@ # ##################################################################### -class FOLDERID: - ProgramFilesX86 = uuid.UUID('{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}') - -# 包装 SHGetKnownFolderPath,来自 https://gist.github.com/mkropat/7550097 -def get_known_folder_path(folderid): - class GUID(ctypes.Structure): - _fields_ = [ - ("Data1", wintypes.DWORD), - ("Data2", wintypes.WORD), - ("Data3", wintypes.WORD), - ("Data4", wintypes.BYTE * 8) - ] - - def __init__(self, uuid_): - ctypes.Structure.__init__(self) - self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid_.fields - for i in range(2, 8): - self.Data4[i] = rest>>(8 - i - 1)*8 & 0xff - - CoTaskMemFree = windll.ole32.CoTaskMemFree - CoTaskMemFree.restype = None - CoTaskMemFree.argtypes = [ctypes.c_void_p] - - SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath - SHGetKnownFolderPath.argtypes = [ - ctypes.POINTER(GUID), - wintypes.DWORD, - wintypes.HANDLE, - ctypes.POINTER(ctypes.c_wchar_p) - ] - - fid = GUID(folderid) - pPath = ctypes.c_wchar_p() - if SHGetKnownFolderPath(ctypes.byref(fid), 0, wintypes.HANDLE(0), ctypes.byref(pPath)) != 0: - raise FileNotFoundError() - path = pPath.value - CoTaskMemFree(pPath) - return path - -programFilesX86Path = get_known_folder_path(FOLDERID.ProgramFilesX86); - +programFilesX86Path = os.path.expandvars("%ProgramFiles(x86)%") vswherePath = programFilesX86Path + "\\Microsoft Visual Studio\\Installer\\vswhere.exe" if not os.access(vswherePath, os.X_OK): raise Exception("未找到 vswhere") -process = subprocess.run(vswherePath + " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe", capture_output=True) +process = subprocess.run( + vswherePath + + " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe", + capture_output=True, +) msbuildPath = str(process.stdout, encoding="utf-8").splitlines()[0] if not os.access(msbuildPath, os.X_OK): raise Exception("未找到 msbuild") @@ -80,19 +42,24 @@ def __init__(self, uuid_): os.chdir(os.path.dirname(__file__)) -if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL") != 0: +cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL' +if os.system(cmd) != 0: raise Exception("编译 CONAN_INSTALL 失败") -if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects") != 0: +cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects' +if os.system(cmd) != 0: raise Exception("编译 Effects 失败") -if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core") != 0: +cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core' +if os.system(cmd) != 0: raise Exception("编译 Magpie.Core 失败") -if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie") != 0: +cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie' +if os.system(cmd) != 0: raise Exception("编译 Magpie 失败") -if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater") != 0: +cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater' +if os.system(cmd) != 0: raise Exception("编译 Updater 失败") ##################################################################### @@ -103,6 +70,7 @@ def __init__(self, uuid_): os.chdir(os.getcwd() + "\\publish") + # 删除文件,忽略错误 def remove_file(file): try: @@ -110,6 +78,7 @@ def remove_file(file): except: pass + # 删除文件夹,忽略错误 def remove_folder(folder): try: @@ -117,6 +86,7 @@ def remove_folder(folder): except: pass + remove_file("Microsoft.Web.WebView2.Core.dll") for pattern in ["*.pdb", "*.lib", "*.exp", "*.winmd", "*.xml", "*.xbf", "dummy.*"]: @@ -125,7 +95,7 @@ def remove_folder(folder): for file in glob.glob("*.pri"): if file != "resources.pri": - remove_file(file) + remove_file(file) for folder in ["Microsoft.UI.Xaml", "Magpie.App"]: remove_folder(folder) @@ -140,24 +110,28 @@ def remove_folder(folder): ##################################################################### # 取最新的 Windows SDK -windowsSdkDir = sorted(glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*"))[-1]; +windowsSdkDir = sorted( + glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*") +)[-1] makepriPath = windowsSdkDir + "\\x64\\makepri.exe" if not os.access(makepriPath, os.X_OK): raise Exception("未找到 makepri") # 将 resources.pri 的内容导出为 xml -if os.system("\"" + makepriPath + "\" dump /dt detailed /o") != 0: +if os.system(f'"{makepriPath}" dump /dt detailed /o') != 0: raise Exception("dump 失败") xmlTree = ElementTree.parse("resources.pri.xml") # 在 xml 中删除冗余资源 -for resourceNode in xmlTree.getroot().findall("ResourceMap/ResourceMapSubtree/ResourceMapSubtree/ResourceMapSubtree/NamedResource"): +for resourceNode in xmlTree.getroot().findall( + "ResourceMap/ResourceMapSubtree/ResourceMapSubtree/ResourceMapSubtree/NamedResource" +): name = resourceNode.get("name") if not name.endswith(".xbf"): continue - + # 我们仅需 19h1 和 21h1 的资源,分别用于 Win10 和 Win11 for key in ["compact", "Compact", "v1", "rs2", "rs3", "rs4", "rs5"]: if key in name: @@ -168,7 +142,8 @@ def remove_folder(folder): xmlTree.write("resources.pri.xml", encoding="utf-8") with open("priconfig.xml", "w", encoding="utf-8") as f: - print(""" + print( + """ @@ -190,10 +165,12 @@ def remove_folder(folder): -""", file=f) +""", + file=f, + ) # 将 xml 重新封装成 pri -os.system("\"" + makepriPath + "\" new /pr . /cf priconfig.xml /in Magpie.App /o") +os.system(f'"{makepriPath}" new /pr . /cf priconfig.xml /in Magpie.App /o') os.remove("resources.pri.xml") os.remove("priconfig.xml") From 8a549d404b45b69214158254c815984e5b78256d Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Thu, 12 Oct 2023 00:16:27 +0800 Subject: [PATCH 28/70] =?UTF-8?q?=E5=B0=86=20wiki.sh=20=E7=A7=BB=E6=A4=8D?= =?UTF-8?q?=E4=B8=BA=20python=20(#729)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 将 wiki.sh 移植为 python * chore: 修复编译 * 测试部署 wiki * chore: 修复 CI 错误 * chore: 更正 wiki CI 触发条件 * chore: 添加日志 * fix: 忽略删除失败 * fix: 忽略清理错误 * fix: 提高 python 版本 * chore: 修复 yml 格式 * fix * fix: 不再清理临时目录 * 结束测试 --- .github/workflows/build.yml | 8 +++++-- .github/workflows/wiki.yml | 13 +++++++---- ci/wiki.py | 46 +++++++++++++++++++++++++++++++++++++ ci/wiki.sh | 32 -------------------------- 4 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 ci/wiki.py delete mode 100755 ci/wiki.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f36073b42..808760b6b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,11 +14,15 @@ on: jobs: build: - runs-on: windows-2022 + runs-on: windows-latest steps: - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Load Conan cache uses: actions/cache@v3 with: @@ -32,7 +36,7 @@ jobs: run: pip install conan<2.0 - name: Build - run: python "publish.py" + run: python publish.py - name: Save hash id: hash diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml index 1d3d61a75..587463285 100644 --- a/.github/workflows/wiki.yml +++ b/.github/workflows/wiki.yml @@ -5,21 +5,24 @@ on: # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ main ] - paths: [ '.github/workflows/wiki.yml', 'docs/**', 'ci/wiki.sh' ] + paths: [ '.github/workflows/wiki.yml', 'docs/**', 'ci/wiki.py' ] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: publish: # The type of runner that the job will run on - runs-on: ubuntu-latest + runs-on: windows-latest # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - - name: Upload Documentation to Wiki - run: ci/wiki.sh - shell: bash + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Upload documentations to wiki + run: python ci/wiki.py env: GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} diff --git a/ci/wiki.py b/ci/wiki.py new file mode 100644 index 000000000..9c5e727c9 --- /dev/null +++ b/ci/wiki.py @@ -0,0 +1,46 @@ +import sys +import os +import tempfile +import glob +import shutil + +try: + # https://docs.github.com/en/actions/learn-github-actions/variables + if os.environ["GITHUB_ACTIONS"].lower() == "true": + # 不知为何在 Github Actions 中运行时默认编码为 ANSI,并且 print 需刷新流才能正常显示 + for stream in [sys.stdout, sys.stderr]: + stream.reconfigure(encoding="utf-8") +except: + pass + +if not "GH_PERSONAL_ACCESS_TOKEN" in os.environ: + raise Exception("未找到环境变量 GH_PERSONAL_ACCESS_TOKEN") + +wikiRepoUrl = os.path.expandvars( + "https://${GH_PERSONAL_ACCESS_TOKEN}@github.com/${GITHUB_REPOSITORY}.wiki.git" +) + +# 创建临时目录 +wikiRepoDir = tempfile.mkdtemp() +os.chdir(wikiRepoDir) + +os.system("git init") +actor = os.environ["GITHUB_ACTOR"] +os.system("git config user.name " + actor) +os.system(f"git config user.email {actor}@users.noreply.github.com") + +# 拉取 +if os.system(f'git pull "{wikiRepoUrl}"') != 0: + raise Exception("git pull 失败") + +# 将文档拷贝到临时目录 +docsDir = os.path.normpath(os.path.dirname(__file__) + "\\..\\docs") +for file in glob.glob(docsDir + "\\*.md"): + shutil.copy(file, wikiRepoDir) + print("已拷贝 " + file, flush=True) + +# 推送 +os.system("git add .") +os.system('git commit -m "Published by CI"') +if os.system(f'git push --set-upstream "{wikiRepoUrl}" master') != 0: + raise Exception("git push 失败") diff --git a/ci/wiki.sh b/ci/wiki.sh deleted file mode 100755 index b041ebf5f..000000000 --- a/ci/wiki.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -if [ -z "$GH_PERSONAL_ACCESS_TOKEN" ]; then - exit 1 -fi - -GIT_REPOSITORY_URL="https://${GH_PERSONAL_ACCESS_TOKEN}@${GITHUB_SERVER_URL#https://}/$GITHUB_REPOSITORY.wiki.git" - -tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX) -( - cd "$tmp_dir" || exit 1 - git init - git config user.name "$GITHUB_ACTOR" - git config user.email "$GITHUB_ACTOR@users.noreply.github.com" - git pull "$GIT_REPOSITORY_URL" -) || exit 1 - -for file in docs/*.md; do - cp "$file" "$tmp_dir" -done - -( - cd "$tmp_dir" || exit 1 - git add . - git commit -m "Published by CI" - git push --set-upstream "$GIT_REPOSITORY_URL" master -) || exit 1 - -rm -rf "$tmp_dir" -exit 0 From 3c70bb0e0c77405061c39c6f23ac1ef41143e0a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Thu, 12 Oct 2023 12:04:16 +0800 Subject: [PATCH 29/70] =?UTF-8?q?chore:=20=E5=B0=86=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E9=80=9A=E7=94=A8=E9=85=8D=E7=BD=AE=E7=A7=BB=E5=88=B0=20Soluti?= =?UTF-8?q?on.props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 10 ++--- src/Magpie.App/Magpie.App.vcxproj | 23 ------------ src/Magpie.Core/Magpie.Core.vcxproj | 27 +------------- src/Magpie/Magpie.vcxproj | 26 ------------- src/Solution.props | 27 +++++++++++++- src/Updater/Updater.vcxproj | 57 ++++++----------------------- src/Updater/conanfile.txt | 6 --- src/Updater/pch.h | 37 ------------------- 8 files changed, 42 insertions(+), 171 deletions(-) delete mode 100644 src/Updater/conanfile.txt diff --git a/Directory.Build.props b/Directory.Build.props index 91511cd1b..06a4c94c6 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -14,11 +14,11 @@ Level4 4251 - - - - - + + + + + %(AdditionalOptions) /await:strict /utf-8 /Zc:__cplusplus /volatile:iso /fp:contract diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index d960278b9..3c99c2795 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -55,15 +55,6 @@ v143 Unicode - - true - true - - - false - true - false - @@ -89,20 +80,6 @@ kernel32.lib;ole32.lib;oleaut32.lib;user32.lib;gdi32.lib;$(OutDir)..\Magpie.Core.lib;%(AdditionalDependencies) - - - _DEBUG;%(PreprocessorDefinitions) - - - - - NDEBUG;%(PreprocessorDefinitions) - - - true - true - - AboutPage.xaml diff --git a/src/Magpie.Core/Magpie.Core.vcxproj b/src/Magpie.Core/Magpie.Core.vcxproj index 96582e0f3..32d0afa89 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj +++ b/src/Magpie.Core/Magpie.Core.vcxproj @@ -34,15 +34,6 @@ v143 Unicode - - true - true - - - false - true - false - @@ -55,26 +46,10 @@ Fast + MAGPIE_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) Windows - true - - - - - _DEBUG;MAGPIE_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - - - - - true - true - NDEBUG;MAGPIE_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - - - true - true diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index 81a3d4c01..b944be0c2 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -40,15 +40,6 @@ v143 Unicode - - true - true - - - false - true - false - @@ -70,23 +61,6 @@ Windows - true - - - - - _DEBUG;%(PreprocessorDefinitions) - - - - - true - true - NDEBUG;%(PreprocessorDefinitions) - - - true - true diff --git a/src/Solution.props b/src/Solution.props index d9a020318..5a8802061 100644 --- a/src/Solution.props +++ b/src/Solution.props @@ -10,8 +10,18 @@ - + + + + true + true + + + false + true + false + @@ -21,17 +31,30 @@ _WINDOWS;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;WINRT_NO_MODULE_LOCK;NOGDICAPMASKS;NOICONS;NOATOM;NOCLIPBOARD;NODRAWTEXT;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;%(PreprocessorDefinitions) /bigobj %(AdditionalOptions) + + true + + + + _DEBUG;%(PreprocessorDefinitions) + + true + NDEBUG;%(PreprocessorDefinitions) + + true + true + - + diff --git a/src/Updater/Updater.vcxproj b/src/Updater/Updater.vcxproj index 15ee4d8a6..27f94f0fb 100644 --- a/src/Updater/Updater.vcxproj +++ b/src/Updater/Updater.vcxproj @@ -1,5 +1,15 @@ + + 16.0 + Win32Proj + {e82b7a20-0557-4dc1-b418-87977d7450a4} + Updater + 10.0.22621.0 + $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + + true + Debug @@ -18,30 +28,12 @@ x64 - - 16.0 - Win32Proj - {e82b7a20-0557-4dc1-b418-87977d7450a4} - Updater - en-US - 10.0.22621.0 - $(SolutionDir)\bin\$(Platform)\$(Configuration)\ - Application v143 Unicode - - true - true - - - false - true - false - @@ -49,42 +41,15 @@ + - Use - pch.h - $(IntDir)pch.pch - Level4 - true - true - stdcpp20 - stdc17 Fast - true - false - /utf-8 /Zc:__cplusplus /volatile:iso %(AdditionalOptions) Windows - true - - - - - _DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - - - true - true - NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - true - true diff --git a/src/Updater/conanfile.txt b/src/Updater/conanfile.txt deleted file mode 100644 index 2d9b796dd..000000000 --- a/src/Updater/conanfile.txt +++ /dev/null @@ -1,6 +0,0 @@ -[requires] -fmt/9.1.0 -spdlog/1.11.0 - -[generators] -visual_studio diff --git a/src/Updater/pch.h b/src/Updater/pch.h index c616060c2..e2bbe9142 100644 --- a/src/Updater/pch.h +++ b/src/Updater/pch.h @@ -6,46 +6,9 @@ #include -#define WIN32_LEAN_AND_MEAN - // Windows 头文件 -// 从 windows.h 里排除不需要的 API -#define NOGDICAPMASKS -#define NOVIRTUALKEYCODE -#define NOWINMESSAGES -#define NOWINSTYLES -#define NOSYSMETRICS -#define NOMENUS -#define NOICONS -#define NOKEYSTATES -#define NOSYSCOMMANDS -#define NORASTEROPS -#define OEMRESOURCE -#define NOATOM -#define NOCLIPBOARD -#define NOCOLOR -#define NOCTLMGR -#define NODRAWTEXT #define NOGDI -#define NOMEMMGR -#define NOMETAFILE -#define NOMINMAX -#define NOMSG -#define NOOPENFILE -#define NOSCROLL -#define NOSERVICE -#define NOSOUND -#define NOTEXTMETRIC -#define NOWH -#define NOWINOFFSETS -#define NOCOMM -#define NOKANJI -#define NOHELP -#define NOPROFILER -#define NODEFERWINDOWPOS -#define NOMCX - #include // C++ 运行时头文件 From 4c19e9ec79c4839f78be0d22a9e44fa48b62a479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Thu, 12 Oct 2023 12:28:13 +0800 Subject: [PATCH 30/70] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E7=9A=84=E6=A0=87=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Solution.props | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Solution.props b/src/Solution.props index 5a8802061..043dfc5b3 100644 --- a/src/Solution.props +++ b/src/Solution.props @@ -45,6 +45,8 @@ true + true + true NDEBUG;%(PreprocessorDefinitions) From 89ca53dc83fc90f2989b7f20c8e4a2b90560b2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Thu, 12 Oct 2023 13:15:14 +0800 Subject: [PATCH 31/70] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 1 + src/Solution.props | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 06a4c94c6..c5fcba15e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,6 +6,7 @@ stdcpp20 + stdc17 true false diff --git a/src/Solution.props b/src/Solution.props index 043dfc5b3..70d316918 100644 --- a/src/Solution.props +++ b/src/Solution.props @@ -19,7 +19,6 @@ false - true false @@ -45,11 +44,13 @@ true + true true true NDEBUG;%(PreprocessorDefinitions) + UseLinkTimeCodeGeneration true true From 7029df738c63b7ef3ba85a701ad027b725d7929e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Fri, 13 Oct 2023 21:50:22 +0800 Subject: [PATCH 32/70] =?UTF-8?q?chore:=20=E5=B0=86=20os.system=20?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E4=B8=BA=20subprocess.run=20os.system=20?= =?UTF-8?q?=E7=9A=84=E5=91=BD=E4=BB=A4=E8=A7=A3=E9=87=8A=E5=99=A8=E7=94=B1?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=86=B3=E5=AE=9A=EF=BC=8C=E5=9B=A0=E6=AD=A4?= =?UTF-8?q?=E4=B8=8D=E5=8F=AF=E9=9D=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ci/wiki.py | 20 +++++++++++++------- publish.py | 33 ++++++++++++++++++--------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ci/wiki.py b/ci/wiki.py index 9c5e727c9..87bb99aad 100644 --- a/ci/wiki.py +++ b/ci/wiki.py @@ -3,6 +3,7 @@ import tempfile import glob import shutil +import subprocess try: # https://docs.github.com/en/actions/learn-github-actions/variables @@ -24,13 +25,17 @@ wikiRepoDir = tempfile.mkdtemp() os.chdir(wikiRepoDir) -os.system("git init") +p = subprocess.run("git init") +if p.returncode != 0: + raise Exception("git init 失败") + actor = os.environ["GITHUB_ACTOR"] -os.system("git config user.name " + actor) -os.system(f"git config user.email {actor}@users.noreply.github.com") +subprocess.run("git config user.name " + actor) +subprocess.run(f"git config user.email {actor}@users.noreply.github.com") # 拉取 -if os.system(f'git pull "{wikiRepoUrl}"') != 0: +p = subprocess.run(f'git pull "{wikiRepoUrl}"') +if p.returncode != 0: raise Exception("git pull 失败") # 将文档拷贝到临时目录 @@ -40,7 +45,8 @@ print("已拷贝 " + file, flush=True) # 推送 -os.system("git add .") -os.system('git commit -m "Published by CI"') -if os.system(f'git push --set-upstream "{wikiRepoUrl}" master') != 0: +subprocess.run("git add .") +subprocess.run('git commit -m "Published by CI"') +p = subprocess.run(f'git push --set-upstream "{wikiRepoUrl}" master') +if p.returncode != 0: raise Exception("git push 失败") diff --git a/publish.py b/publish.py index 0d1f43030..81bd66568 100644 --- a/publish.py +++ b/publish.py @@ -20,17 +20,17 @@ # ##################################################################### -programFilesX86Path = os.path.expandvars("%ProgramFiles(x86)%") +programFilesX86Path = os.environ["ProgramFiles(x86)"] vswherePath = programFilesX86Path + "\\Microsoft Visual Studio\\Installer\\vswhere.exe" if not os.access(vswherePath, os.X_OK): raise Exception("未找到 vswhere") -process = subprocess.run( +p = subprocess.run( vswherePath + " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe", capture_output=True, ) -msbuildPath = str(process.stdout, encoding="utf-8").splitlines()[0] +msbuildPath = str(p.stdout, encoding="utf-8").splitlines()[0] if not os.access(msbuildPath, os.X_OK): raise Exception("未找到 msbuild") @@ -42,24 +42,24 @@ os.chdir(os.path.dirname(__file__)) -cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL' -if os.system(cmd) != 0: +p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL') +if p.returncode != 0: raise Exception("编译 CONAN_INSTALL 失败") -cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects' -if os.system(cmd) != 0: +p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects') +if p.returncode != 0: raise Exception("编译 Effects 失败") -cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core' -if os.system(cmd) != 0: +p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core') +if p.returncode != 0: raise Exception("编译 Magpie.Core 失败") -cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie' -if os.system(cmd) != 0: +p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie') +if p.returncode != 0: raise Exception("编译 Magpie 失败") -cmd = f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater' -if os.system(cmd) != 0: +p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater') +if p.returncode != 0: raise Exception("编译 Updater 失败") ##################################################################### @@ -118,7 +118,8 @@ def remove_folder(folder): raise Exception("未找到 makepri") # 将 resources.pri 的内容导出为 xml -if os.system(f'"{makepriPath}" dump /dt detailed /o') != 0: +p = subprocess.run(f'"{makepriPath}" dump /dt detailed /o') +if p.returncode != 0: raise Exception("dump 失败") xmlTree = ElementTree.parse("resources.pri.xml") @@ -170,7 +171,9 @@ def remove_folder(folder): ) # 将 xml 重新封装成 pri -os.system(f'"{makepriPath}" new /pr . /cf priconfig.xml /in Magpie.App /o') +p = subprocess.run(f'"{makepriPath}" new /pr . /cf priconfig.xml /in Magpie.App /o') +if p.returncode != 0: + raise Exception("makepri 失败") os.remove("resources.pri.xml") os.remove("priconfig.xml") From fd0749456b6502c071d02d30aa50f69e0c5b6826 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Sat, 14 Oct 2023 14:21:35 +0800 Subject: [PATCH 33/70] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E7=BC=96=E8=AF=91=20Co?= =?UTF-8?q?nan=20=E4=BE=9D=E8=B5=96=20(#730)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 使用 MSBuild 自动编译 Conan 依赖 * chore: 使用 python 脚本编译 Conan 有一个问题是第一次编译将会失败,因为 VS 缓存了 Solution.props,不会自动导入 conanbuildinfo.props * chore: 更新 CONAN_INSTALL * Revert "chore: 使用 MSBuild 自动编译 Conan 依赖" This reverts commit b5531986acfac5c4fbe734937b9dfcfb5b7fc08b. * chore: 使用 CONAN_INSTALL 作为跳板实现自动编译 Conan 依赖 CONAN_INSTALL 为依赖项,因此是不同的构建,避免了缓存问题 * chore: 简化编译 CI 已支持直接编译 sln * 测试 * Revert "测试" This reverts commit 97042bd8e0abd2a3a2b7a1549dc8e23b92925738. * chore: CONAN_INSTALL 改名 _ConanDeps * docs: 更新编译指南 * chore: 优化 _ConanDeps --- .github/workflows/build.yml | 9 ++-- Magpie.sln | 12 ++++- docs/Compilation guide.md | 8 +-- ...26\350\257\221\346\214\207\345\215\227.md" | 8 +-- publish.py | 24 ++------- src/CONAN_INSTALL/ConanInstall.bat | 30 ----------- .../_ConanDeps.filters} | 2 +- .../_ConanDeps.vcxproj} | 41 ++------------ src/_ConanDeps/build_conan_deps.py | 54 +++++++++++++++++++ 9 files changed, 83 insertions(+), 105 deletions(-) delete mode 100644 src/CONAN_INSTALL/ConanInstall.bat rename src/{CONAN_INSTALL/CONAN_INSTALL.vcxproj.filters => _ConanDeps/_ConanDeps.filters} (79%) rename src/{CONAN_INSTALL/CONAN_INSTALL.vcxproj => _ConanDeps/_ConanDeps.vcxproj} (57%) create mode 100644 src/_ConanDeps/build_conan_deps.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 808760b6b..49b18306a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,18 +23,15 @@ jobs: with: python-version: '3.11' + - name: Setup Conan + run: pip install conan<2.0 + - name: Load Conan cache uses: actions/cache@v3 with: path: ./.conan/data key: ${{ runner.os }}-conan-${{ hashFiles('src/**/conanfile.txt') }} - - name: Restore NuGet packages - run: nuget restore - - - name: Setup Conan - run: pip install conan<2.0 - - name: Build run: python publish.py diff --git a/Magpie.sln b/Magpie.sln index e07e2db8e..723459014 100644 --- a/Magpie.sln +++ b/Magpie.sln @@ -6,6 +6,7 @@ MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Magpie", "src\Magpie\Magpie.vcxproj", "{1801171B-65B6-400F-92FF-73EAF499CFB3}" ProjectSection(ProjectDependencies) = postProject {1239537C-E5B8-427A-9E7F-EA443D1F3529} = {1239537C-E5B8-427A-9E7F-EA443D1F3529} + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} = {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} {62503530-B84B-4CC2-80B6-3F89618172B7} = {62503530-B84B-4CC2-80B6-3F89618172B7} {E82B7A20-0557-4DC1-B418-87977D7450A4} = {E82B7A20-0557-4DC1-B418-87977D7450A4} EndProjectSection @@ -13,6 +14,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Magpie.App", "src\Magpie.App\Magpie.App.vcxproj", "{1239537C-E5B8-427A-9E7F-EA443D1F3529}" ProjectSection(ProjectDependencies) = postProject {0E5205AE-DFA9-4CB8-B662-E43CD6512E2A} = {0E5205AE-DFA9-4CB8-B662-E43CD6512E2A} + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} = {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{00AB63C3-0CD3-4944-B8E6-58C86138618D}" @@ -25,11 +27,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "src\Shared\Shared.vcxitems", "{4EB33017-68C1-40FE-877A-BCFAB2832F18}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CONAN_INSTALL", "src\CONAN_INSTALL\CONAN_INSTALL.vcxproj", "{456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ConanDeps", "src\_ConanDeps\_ConanDeps.vcxproj", "{456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Effects", "src\Effects\Effects.vcxproj", "{62503530-B84B-4CC2-80B6-3F89618172B7}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Magpie.Core", "src\Magpie.Core\Magpie.Core.vcxproj", "{0E5205AE-DFA9-4CB8-B662-E43CD6512E2A}" + ProjectSection(ProjectDependencies) = postProject + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} = {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} + EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Natvis", "Natvis", "{9808D34F-5715-4D02-B216-4CB80F46BBC0}" ProjectSection(SolutionItems) = preProject @@ -65,9 +70,13 @@ Global {1239537C-E5B8-427A-9E7F-EA443D1F3529}.Release|x64.ActiveCfg = Release|x64 {1239537C-E5B8-427A-9E7F-EA443D1F3529}.Release|x64.Build.0 = Release|x64 {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Debug|ARM64.Build.0 = Debug|ARM64 {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Debug|x64.ActiveCfg = Debug|x64 + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Debug|x64.Build.0 = Debug|x64 {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Release|ARM64.ActiveCfg = Release|ARM64 + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Release|ARM64.Build.0 = Release|ARM64 {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Release|x64.ActiveCfg = Release|x64 + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D}.Release|x64.Build.0 = Release|x64 {62503530-B84B-4CC2-80B6-3F89618172B7}.Debug|ARM64.ActiveCfg = Debug|ARM64 {62503530-B84B-4CC2-80B6-3F89618172B7}.Debug|ARM64.Build.0 = Debug|ARM64 {62503530-B84B-4CC2-80B6-3F89618172B7}.Debug|x64.ActiveCfg = Debug|x64 @@ -97,6 +106,7 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {456CCAE4-2C51-4CF2-8D3A-1EFCE8C41A2D} = {00AB63C3-0CD3-4944-B8E6-58C86138618D} {9808D34F-5715-4D02-B216-4CB80F46BBC0} = {00AB63C3-0CD3-4944-B8E6-58C86138618D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/docs/Compilation guide.md b/docs/Compilation guide.md index b2ca1af49..0174b574b 100644 --- a/docs/Compilation guide.md +++ b/docs/Compilation guide.md @@ -21,7 +21,7 @@ In order to compile Magpie, you need to first install: conan --version ``` -### Compile and Run +### Compile 1. Clone the repo @@ -29,8 +29,4 @@ In order to compile Magpie, you need to first install: git clone https://github.com/Blinue/Magpie ``` -2. Open the Magpie.sln in the root directory using Visual Studio 2022. This solution contains multiple projects, among which the "Magpie" project is the program's entry point. It should already be the startup project, but if it isn't, please set it manually. - -3. First, build the "CONAN_INSTALL" project, which will install the dependencies. - -4. Compile and run Magpie. +2. Open the Magpie.sln in the root directory and build the solution. diff --git "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" index e7d0e7c80..0d4c7bde8 100644 --- "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" +++ "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" @@ -21,7 +21,7 @@ conan --version ``` -## 编译和运行 +## 编译 1. 克隆存储库 @@ -29,8 +29,4 @@ git clone https://github.com/Blinue/Magpie ``` -2. 使用 Visual Studio 2022 打开根目录的 Magpie.sln,此解决方案包含多个项目,其中“Magpie”项目是程序入口。它应该已经是启动项目,如果不是请手动设置。 - -3. 首先生成 CONAN_INSTALL 项目,这将编译依赖项。 - -4. 编译和运行“Magpie”项目。 +2. 打开根目录的 Magpie.sln 然后生成解决方案。 diff --git a/publish.py b/publish.py index 81bd66568..f777e56c4 100644 --- a/publish.py +++ b/publish.py @@ -42,25 +42,11 @@ os.chdir(os.path.dirname(__file__)) -p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL') -if p.returncode != 0: - raise Exception("编译 CONAN_INSTALL 失败") - -p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects') -if p.returncode != 0: - raise Exception("编译 Effects 失败") - -p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core') -if p.returncode != 0: - raise Exception("编译 Magpie.Core 失败") - -p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie') -if p.returncode != 0: - raise Exception("编译 Magpie 失败") - -p = subprocess.run(f'"{msbuildPath}" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater') +p = subprocess.run( + f'"{msbuildPath}" -restore -p:RestorePackagesConfig=true;Configuration=Release;Platform=x64;OutDir={os.getcwd()}\\publish\\ Magpie.sln' +) if p.returncode != 0: - raise Exception("编译 Updater 失败") + raise Exception("编译失败") ##################################################################### # @@ -68,7 +54,7 @@ # ##################################################################### -os.chdir(os.getcwd() + "\\publish") +os.chdir("publish") # 删除文件,忽略错误 diff --git a/src/CONAN_INSTALL/ConanInstall.bat b/src/CONAN_INSTALL/ConanInstall.bat deleted file mode 100644 index 701fdf780..000000000 --- a/src/CONAN_INSTALL/ConanInstall.bat +++ /dev/null @@ -1,30 +0,0 @@ -conan --version - -IF %ERRORLEVEL% NEQ 0 ( - ECHO Error: Conan not found - EXIT 1 -) - -conan config set storage.path=%CD%\..\..\.conan\data - -IF %1 == Debug ( - IF %2 == x64 ( - conan install ..\Magpie\conanfile.txt --install-folder ..\..\.conan\x64\Debug\Magpie --build=outdated -s build_type=Debug -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MTd --update - conan install ..\Magpie.Core\conanfile.txt --install-folder ..\..\.conan\x64\Debug\Magpie.Core --build=outdated -s build_type=Debug -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MTd --update - conan install ..\Magpie.App\conanfile.txt --install-folder ..\..\.conan\x64\Debug\Magpie.App --build=outdated -s build_type=Debug -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MTd --update - ) ELSE ( - conan install ..\Magpie\conanfile.txt --install-folder ..\..\.conan\ARM64\Debug\Magpie --build=outdated -s build_type=Debug -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MTd --update - conan install ..\Magpie.Core\conanfile.txt --install-folder ..\..\.conan\ARM64\Debug\Magpie.Core --build=outdated -s build_type=Debug -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MTd --update - conan install ..\Magpie.App\conanfile.txt --install-folder ..\..\.conan\ARM64\Debug\Magpie.App --build=outdated -s build_type=Debug -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MTd --update - ) -) ELSE ( - IF %2 == x64 ( - conan install ..\Magpie\conanfile.txt --install-folder ..\..\.conan\x64\Release\Magpie --build=outdated -s build_type=Release -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MT --update - conan install ..\Magpie.Core\conanfile.txt --install-folder ..\..\.conan\x64\Release\Magpie.Core --build=outdated -s build_type=Release -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MT --update - conan install ..\Magpie.App\conanfile.txt --install-folder ..\..\.conan\x64\Release\Magpie.App --build=outdated -s build_type=Release -s arch=x86_64 -s compiler.version=17 -s compiler.runtime=MT --update - ) ELSE ( - conan install ..\Magpie\conanfile.txt --install-folder ..\..\.conan\ARM64\Release\Magpie --build=outdated -s build_type=Release -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MT --update - conan install ..\Magpie.Core\conanfile.txt --install-folder ..\..\.conan\ARM64\Release\Magpie.Core --build=outdated -s build_type=Release -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MT --update - conan install ..\Magpie.App\conanfile.txt --install-folder ..\..\.conan\ARM64\Release\Magpie.App --build=outdated -s build_type=Release -s arch=armv8 -s compiler.version=17 -s compiler.runtime=MT --update - ) -) diff --git a/src/CONAN_INSTALL/CONAN_INSTALL.vcxproj.filters b/src/_ConanDeps/_ConanDeps.filters similarity index 79% rename from src/CONAN_INSTALL/CONAN_INSTALL.vcxproj.filters rename to src/_ConanDeps/_ConanDeps.filters index d50e43dad..b388e6a8d 100644 --- a/src/CONAN_INSTALL/CONAN_INSTALL.vcxproj.filters +++ b/src/_ConanDeps/_ConanDeps.filters @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/CONAN_INSTALL/CONAN_INSTALL.vcxproj b/src/_ConanDeps/_ConanDeps.vcxproj similarity index 57% rename from src/CONAN_INSTALL/CONAN_INSTALL.vcxproj rename to src/_ConanDeps/_ConanDeps.vcxproj index 8a8ebea1b..ac6c35397 100644 --- a/src/CONAN_INSTALL/CONAN_INSTALL.vcxproj +++ b/src/_ConanDeps/_ConanDeps.vcxproj @@ -22,10 +22,10 @@ 16.0 Win32Proj {456ccae4-2c51-4cf2-8d3a-1efce8c41a2d} - CONANINSTALL 10.0 $(SolutionDir)\bin\$(Platform)\$(Configuration)\ $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + true $(MSBuildWarningsAsMessages);MSB8065 @@ -35,46 +35,15 @@ Utility v143 - - - .\ConanInstall.bat Debug x64 - - - RD /S /Q ..\..\obj\x64\Debug\CONAN_INSTALL\CONAN_INSTALL.tlog - - - - - .\ConanInstall.bat Release x64 - - - RD /S /Q ..\..\obj\x64\Release\CONAN_INSTALL\CONAN_INSTALL.tlog - - - - - .\ConanInstall.bat Debug ARM64 - - - RD /S /Q ..\..\obj\ARM64\Debug\CONAN_INSTALL\CONAN_INSTALL.tlog - - - - - .\ConanInstall.bat Release ARM64 - - - RD /S /Q ..\..\obj\ARM64\Release\CONAN_INSTALL\CONAN_INSTALL.tlog - - - - - + + + + \ No newline at end of file diff --git a/src/_ConanDeps/build_conan_deps.py b/src/_ConanDeps/build_conan_deps.py new file mode 100644 index 000000000..cee0addf0 --- /dev/null +++ b/src/_ConanDeps/build_conan_deps.py @@ -0,0 +1,54 @@ +import sys +import os +import hashlib +import subprocess + +if len(sys.argv) != 3: + raise Exception("请勿直接运行此脚本") + +platform = sys.argv[1] +configuration = sys.argv[2] + +if not platform in ["x64", "ARM64"] or not configuration in ["Debug", "Release"]: + raise Exception("非法参数") + +subprocess.run(f"conan config set storage.path={os.getcwd()}\\..\\..\\.conan\\data") + +# 遍历存在 conanfile.txt 的项目 +for project in os.listdir(".."): + conanfilePath = f"..\\{project}\\conanfile.txt" + try: + with open(conanfilePath, "rb") as conanfile: + hash = hashlib.file_digest(conanfile, hashlib.sha256).hexdigest() + except: + continue + + hashFilePath = f"..\\..\\.conan\\{platform}\\{configuration}\\{project}\\hash.txt" + try: + with open(hashFilePath, "r") as hashFile: + if hashFile.read(len(hash)) == hash: + # 哈希未变化 + continue + except: + pass + + # 编译依赖 + if platform == "x64": + build_type = "x86_64" + else: + build_type = "armv8" + + if configuration == "Debug": + runtime = "MTd" + else: + runtime = "MT" + + p = subprocess.run( + f"conan install {conanfilePath} --install-folder ..\\..\\.conan\\{platform}\\{configuration}\\{project} --build=outdated -s build_type={configuration} -s arch={build_type} -s compiler.version=17 -s compiler.runtime={runtime} --update" + ) + if p.returncode != 0: + raise Exception("conan install 失败") + + # 更新哈希文件 + with open(hashFilePath, "w") as hashFile: + print(hash, file=hashFile) From 8196a98f6e280a5fda1176c94441be017ec724a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sat, 14 Oct 2023 14:53:40 +0800 Subject: [PATCH 34/70] =?UTF-8?q?chore:=20=E6=B8=85=E7=90=86=20=5FConanDep?= =?UTF-8?q?s=20=E5=B0=86=E6=B8=85=E7=90=86=20Conan=20=E7=94=9F=E6=88=90=20?= =?UTF-8?q?props=20=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_ConanDeps/_ConanDeps.vcxproj | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/_ConanDeps/_ConanDeps.vcxproj b/src/_ConanDeps/_ConanDeps.vcxproj index ac6c35397..f518314ee 100644 --- a/src/_ConanDeps/_ConanDeps.vcxproj +++ b/src/_ConanDeps/_ConanDeps.vcxproj @@ -43,7 +43,14 @@ - + + + + + ..\\..\\.conan\\$(Platform)\\$(Configuration) + + + \ No newline at end of file From ae9895a488393c16291b023cb6617fb260ac1dc1 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 10:33:06 +0800 Subject: [PATCH 35/70] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E5=88=B0=20Conan=20v2?= =?UTF-8?q?=20(#731)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 迁移到 Conan v2 * docs: 更新文档 * chore: 更新 Conan 缓存路径 * chore: 所有 Conan 依赖都是最新的则显示消息 --- .conan/.gitignore | 3 --- .conan/Directory.Build.props | 5 ----- .github/workflows/build.yml | 4 ++-- .gitignore | 1 + docs/Compilation guide.md | 3 +-- ...226\350\257\221\346\214\207\345\215\227.md" | 3 +-- src/Magpie.App/conanfile.txt | 6 ++---- src/Magpie.Core/conanfile.txt | 6 ++---- src/Magpie/conanfile.txt | 6 ++---- src/Solution.props | 2 +- src/_ConanDeps/_ConanDeps.vcxproj | 7 +++++-- src/_ConanDeps/build_conan_deps.py | 18 ++++++++++-------- src/_ConanDeps/conanprofile.txt | 5 +++++ 13 files changed, 32 insertions(+), 37 deletions(-) delete mode 100644 .conan/.gitignore delete mode 100644 .conan/Directory.Build.props create mode 100644 src/_ConanDeps/conanprofile.txt diff --git a/.conan/.gitignore b/.conan/.gitignore deleted file mode 100644 index a8b05297c..000000000 --- a/.conan/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -* -!.gitignore -!Directory.Build.props diff --git a/.conan/Directory.Build.props b/.conan/Directory.Build.props deleted file mode 100644 index 3f0d118b8..000000000 --- a/.conan/Directory.Build.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49b18306a..d2ad69846 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,12 +24,12 @@ jobs: python-version: '3.11' - name: Setup Conan - run: pip install conan<2.0 + run: pip install conan - name: Load Conan cache uses: actions/cache@v3 with: - path: ./.conan/data + path: ~/.conan2/p key: ${{ runner.os }}-conan-${{ hashFiles('src/**/conanfile.txt') }} - name: Build diff --git a/.gitignore b/.gitignore index 3a17bb0d0..d6bc95200 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ ## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore +.conan/ my_*/ # User-specific files diff --git a/docs/Compilation guide.md b/docs/Compilation guide.md index 0174b574b..218ef347a 100644 --- a/docs/Compilation guide.md +++ b/docs/Compilation guide.md @@ -10,9 +10,8 @@ In order to compile Magpie, you need to first install: 4. [Conan](https://conan.io/) v1 ```bash - pip install conan<2.0 + pip install conan ``` - To execute in cmd, double quotes should be added around `conan<2.0`. Make sure that the above dependencies have been added to the system path, and use the following commands to check: ```bash diff --git "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" index 0d4c7bde8..55e5e0724 100644 --- "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" +++ "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" @@ -10,9 +10,8 @@ 4. [Conan](https://conan.io/) v1 ```bash - pip install conan<2.0 + pip install conan ``` - 在 cmd 中执行应在`conan<2.0`两侧加双引号。 确保上述依赖均已被添加入系统路径,使用以下命令检查: ```bash diff --git a/src/Magpie.App/conanfile.txt b/src/Magpie.App/conanfile.txt index 097a58b82..039b3c6fc 100644 --- a/src/Magpie.App/conanfile.txt +++ b/src/Magpie.App/conanfile.txt @@ -6,9 +6,7 @@ rapidjson/cci.20220822 kuba-zip/0.2.6 [generators] -visual_studio +MSBuildDeps [options] -fmt:header_only=True -spdlog:header_only=True -spdlog:no_exceptions=True +spdlog/*:no_exceptions=True diff --git a/src/Magpie.Core/conanfile.txt b/src/Magpie.Core/conanfile.txt index bbaf0d6fb..f59e53d05 100644 --- a/src/Magpie.Core/conanfile.txt +++ b/src/Magpie.Core/conanfile.txt @@ -7,9 +7,7 @@ yas/7.1.0 imgui/1.89.9 [generators] -visual_studio +MSBuildDeps [options] -fmt:header_only=True -spdlog:header_only=True -spdlog:no_exceptions=True +spdlog/*:no_exceptions=True diff --git a/src/Magpie/conanfile.txt b/src/Magpie/conanfile.txt index 7859ae018..4a214d2e0 100644 --- a/src/Magpie/conanfile.txt +++ b/src/Magpie/conanfile.txt @@ -4,9 +4,7 @@ spdlog/1.12.0 parallel-hashmap/1.37 [generators] -visual_studio +MSBuildDeps [options] -fmt:header_only=True -spdlog:header_only=True -spdlog:no_exceptions=True +spdlog/*:no_exceptions=True diff --git a/src/Solution.props b/src/Solution.props index 70d316918..2dac9b7f9 100644 --- a/src/Solution.props +++ b/src/Solution.props @@ -58,6 +58,6 @@ - + diff --git a/src/_ConanDeps/_ConanDeps.vcxproj b/src/_ConanDeps/_ConanDeps.vcxproj index f518314ee..7d79e9253 100644 --- a/src/_ConanDeps/_ConanDeps.vcxproj +++ b/src/_ConanDeps/_ConanDeps.vcxproj @@ -42,14 +42,17 @@ + + + - + - ..\\..\\.conan\\$(Platform)\\$(Configuration) + ..\\..\\.conan diff --git a/src/_ConanDeps/build_conan_deps.py b/src/_ConanDeps/build_conan_deps.py index cee0addf0..567f2faff 100644 --- a/src/_ConanDeps/build_conan_deps.py +++ b/src/_ConanDeps/build_conan_deps.py @@ -12,7 +12,8 @@ if not platform in ["x64", "ARM64"] or not configuration in ["Debug", "Release"]: raise Exception("非法参数") -subprocess.run(f"conan config set storage.path={os.getcwd()}\\..\\..\\.conan\\data") +# 记录是否有项目的依赖需要编译 +anyProjectToBuild = False # 遍历存在 conanfile.txt 的项目 for project in os.listdir(".."): @@ -23,7 +24,7 @@ except: continue - hashFilePath = f"..\\..\\.conan\\{platform}\\{configuration}\\{project}\\hash.txt" + hashFilePath = f"..\\..\\.conan\\{project}\\{platform}_{configuration}_hash.txt" try: with open(hashFilePath, "r") as hashFile: if hashFile.read(len(hash)) == hash: @@ -32,19 +33,17 @@ except: pass + anyProjectToBuild = True + # 编译依赖 if platform == "x64": build_type = "x86_64" else: build_type = "armv8" - if configuration == "Debug": - runtime = "MTd" - else: - runtime = "MT" - + # HybridCRT 要求静态链接 CRT p = subprocess.run( - f"conan install {conanfilePath} --install-folder ..\\..\\.conan\\{platform}\\{configuration}\\{project} --build=outdated -s build_type={configuration} -s arch={build_type} -s compiler.version=17 -s compiler.runtime={runtime} --update" + f"conan install {conanfilePath} -pr:b=conanprofile.txt -pr:h=conanprofile.txt --output-folder ..\\..\\.conan\\{project} --build=missing -s build_type={configuration} -s arch={build_type} --update" ) if p.returncode != 0: raise Exception("conan install 失败") @@ -52,3 +51,6 @@ # 更新哈希文件 with open(hashFilePath, "w") as hashFile: print(hash, file=hashFile) + +if not anyProjectToBuild: + print("Conan 依赖已是最新", flush=True) diff --git a/src/_ConanDeps/conanprofile.txt b/src/_ConanDeps/conanprofile.txt new file mode 100644 index 000000000..a8f025d5a --- /dev/null +++ b/src/_ConanDeps/conanprofile.txt @@ -0,0 +1,5 @@ +[settings] +compiler=msvc +compiler.runtime=static +compiler.version=193 +os=Windows From 2e804decee2123b41cd174884752f6a08023623c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 12:09:06 +0800 Subject: [PATCH 36/70] =?UTF-8?q?chroe:=20=E5=B0=86=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=A7=BB=E5=85=A5=20Common.*.props?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Magpie.sln | 3 ++- src/{Solution.props => Common.Post.props} | 0 src/Common.Pre.props | 21 +++++++++++++++++++ src/Effects/Effects.vcxproj | 19 +---------------- src/Magpie.App/Magpie.App.vcxproj | 25 ++--------------------- src/Magpie.Core/Magpie.Core.vcxproj | 21 ++----------------- src/Magpie/Magpie.vcxproj | 21 ++----------------- src/Updater/Updater.vcxproj | 21 ++----------------- 8 files changed, 32 insertions(+), 99 deletions(-) rename src/{Solution.props => Common.Post.props} (100%) create mode 100644 src/Common.Pre.props diff --git a/Magpie.sln b/Magpie.sln index 723459014..c2966d90e 100644 --- a/Magpie.sln +++ b/Magpie.sln @@ -21,8 +21,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig Directory.Build.props = Directory.Build.props + src\Common.Pre.props = src\Common.Pre.props + src\Common.Post.props = src\Common.Post.props HybridCRT.props = HybridCRT.props - src\Solution.props = src\Solution.props EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "src\Shared\Shared.vcxitems", "{4EB33017-68C1-40FE-877A-BCFAB2832F18}" diff --git a/src/Solution.props b/src/Common.Post.props similarity index 100% rename from src/Solution.props rename to src/Common.Post.props diff --git a/src/Common.Pre.props b/src/Common.Pre.props new file mode 100644 index 000000000..8c2317c86 --- /dev/null +++ b/src/Common.Pre.props @@ -0,0 +1,21 @@ + + + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + diff --git a/src/Effects/Effects.vcxproj b/src/Effects/Effects.vcxproj index c2c7ebae6..bbb6bf1e2 100644 --- a/src/Effects/Effects.vcxproj +++ b/src/Effects/Effects.vcxproj @@ -1,23 +1,5 @@ - - - Debug - ARM64 - - - Debug - x64 - - - Release - ARM64 - - - Release - x64 - - 16.0 Win32Proj @@ -28,6 +10,7 @@ $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + Utility v143 diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index 3c99c2795..06bfa9b5c 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -32,24 +32,7 @@ false - - - Debug - ARM64 - - - Debug - x64 - - - Release - ARM64 - - - Release - x64 - - + DynamicLibrary v143 @@ -60,12 +43,8 @@ - - - - - + diff --git a/src/Magpie.Core/Magpie.Core.vcxproj b/src/Magpie.Core/Magpie.Core.vcxproj index 32d0afa89..f3029d22b 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj +++ b/src/Magpie.Core/Magpie.Core.vcxproj @@ -1,24 +1,6 @@ - - - Debug - ARM64 - - - Debug - x64 - - - Release - ARM64 - - - Release - x64 - - 16.0 Win32Proj @@ -29,6 +11,7 @@ $(SolutionDir)\bin\$(Platform)\$(Configuration)\ + DynamicLibrary v143 @@ -40,7 +23,7 @@ - + diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index b944be0c2..184985f6a 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -2,24 +2,6 @@ - - - Debug - ARM64 - - - Debug - x64 - - - Release - ARM64 - - - Release - x64 - - 16.0 Win32Proj @@ -35,6 +17,7 @@ true + Application v143 @@ -45,7 +28,7 @@ - + diff --git a/src/Updater/Updater.vcxproj b/src/Updater/Updater.vcxproj index 27f94f0fb..ce82ec70e 100644 --- a/src/Updater/Updater.vcxproj +++ b/src/Updater/Updater.vcxproj @@ -10,24 +10,6 @@ true - - - Debug - ARM64 - - - Debug - x64 - - - Release - ARM64 - - - Release - x64 - - Application @@ -35,13 +17,14 @@ Unicode + - + From 2421acc7b708613f1c9e08013067de65ba052ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 18:19:59 +0800 Subject: [PATCH 37/70] =?UTF-8?q?chore:=20=E5=B0=86=20CJKCharacterSetForIm?= =?UTF-8?q?Gui=20=E5=B7=A5=E5=85=B7=E7=A7=BB=E6=A4=8D=E4=B8=BA=20python=20?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_ConanDeps/build_conan_deps.py | 2 + .../CJKCharacterSetForImGui.sln | 25 ----- .../CJKCharacterSetForImGui.vcxproj | 89 --------------- .../CJKCharacterSetForImGui.vcxproj.filters | 22 ---- tools/CJKCharacterSetForImGui/README.md | 3 - tools/CJKCharacterSetForImGui/main.cpp | 106 ------------------ .../characters.txt} | 0 .../cjk_charset_for_imgui.py | 52 +++++++++ 8 files changed, 54 insertions(+), 245 deletions(-) delete mode 100644 tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.sln delete mode 100644 tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj delete mode 100644 tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj.filters delete mode 100644 tools/CJKCharacterSetForImGui/README.md delete mode 100644 tools/CJKCharacterSetForImGui/main.cpp rename tools/{CJKCharacterSetForImGui/input.txt => CJKCharsetForImGui/characters.txt} (100%) create mode 100644 tools/CJKCharsetForImGui/cjk_charset_for_imgui.py diff --git a/src/_ConanDeps/build_conan_deps.py b/src/_ConanDeps/build_conan_deps.py index 567f2faff..a3517c26c 100644 --- a/src/_ConanDeps/build_conan_deps.py +++ b/src/_ConanDeps/build_conan_deps.py @@ -12,6 +12,8 @@ if not platform in ["x64", "ARM64"] or not configuration in ["Debug", "Release"]: raise Exception("非法参数") +os.chdir(os.path.dirname(__file__)) + # 记录是否有项目的依赖需要编译 anyProjectToBuild = False diff --git a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.sln b/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.sln deleted file mode 100644 index f7f98cb83..000000000 --- a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.5.33627.172 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CJKCharacterSetForImGui", "CJKCharacterSetForImGui.vcxproj", "{E0E023BE-72A6-45BA-A3DE-07E4F7EB5EB7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E0E023BE-72A6-45BA-A3DE-07E4F7EB5EB7}.Debug|x64.ActiveCfg = Debug|x64 - {E0E023BE-72A6-45BA-A3DE-07E4F7EB5EB7}.Debug|x64.Build.0 = Debug|x64 - {E0E023BE-72A6-45BA-A3DE-07E4F7EB5EB7}.Release|x64.ActiveCfg = Release|x64 - {E0E023BE-72A6-45BA-A3DE-07E4F7EB5EB7}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {428064E2-6EE8-4B12-A569-092F40898C06} - EndGlobalSection -EndGlobal diff --git a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj b/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj deleted file mode 100644 index 63210ce1a..000000000 --- a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj +++ /dev/null @@ -1,89 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {e0e023be-72a6-45ba-a3de-07e4f7eb5eb7} - CJKCharacterSetForImGui - 10.0 - CJKCharacterSetForImGui - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp20 - false - /utf-8 /Zc:__cplusplus /volatile:iso %(AdditionalOptions) - Fast - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp20 - false - /utf-8 /Zc:__cplusplus /volatile:iso %(AdditionalOptions) - Fast - - - Console - true - true - true - - - - - - - - - \ No newline at end of file diff --git a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj.filters b/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj.filters deleted file mode 100644 index 65fa6d5ae..000000000 --- a/tools/CJKCharacterSetForImGui/CJKCharacterSetForImGui.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - 源文件 - - - \ No newline at end of file diff --git a/tools/CJKCharacterSetForImGui/README.md b/tools/CJKCharacterSetForImGui/README.md deleted file mode 100644 index 6feab5d85..000000000 --- a/tools/CJKCharacterSetForImGui/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# CJKCharacterSetForImGui - -用于导出供 ImGui 使用的字符表,格式为 https://github.com/ocornut/imgui/blob/bcfc1ad8f63997751a7269788511157ed872da2c/imgui_draw.cpp#L2883 。 diff --git a/tools/CJKCharacterSetForImGui/main.cpp b/tools/CJKCharacterSetForImGui/main.cpp deleted file mode 100644 index f80b30879..000000000 --- a/tools/CJKCharacterSetForImGui/main.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -struct HandleCloser { void operator()(HANDLE h) noexcept { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } }; -using ScopedHandle = std::unique_ptr::type, HandleCloser>; - -static HANDLE SafeHandle(HANDLE h) noexcept { - return (h == INVALID_HANDLE_VALUE) ? nullptr : h; -} - -static std::vector ReadFile(const wchar_t* fileName) noexcept { - CREATEFILE2_EXTENDED_PARAMETERS extendedParams = {}; - extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); - extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN; - extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS; - extendedParams.lpSecurityAttributes = nullptr; - extendedParams.hTemplateFile = nullptr; - - ScopedHandle hFile(SafeHandle(CreateFile2(fileName, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extendedParams))); - - if (!hFile) { - return {}; - } - - DWORD size = GetFileSize(hFile.get(), nullptr); - std::vector result(size, 0); - - DWORD readed; - if (!::ReadFile(hFile.get(), result.data(), size, &readed, nullptr)) { - return {}; - } - - return result; -} - -static std::wstring UTF8ToUTF16(std::string_view str) noexcept { - if (str.empty()) { - return {}; - } - - int convertResult = MultiByteToWideChar(CP_UTF8, 0, - str.data(), (int)str.size(), nullptr, 0); - if (convertResult <= 0) { - assert(false); - return {}; - } - - std::wstring result(convertResult + 10, L'\0'); - convertResult = MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), - result.data(), (int)result.size()); - if (convertResult <= 0) { - assert(false); - return {}; - } - - result.resize(convertResult); - return result; -} - -// 输入: input.txt -// 将输出输入文件中所有汉字组成的字符表 -int main() { - std::vector input = ReadFile(L"input.txt"); - input.push_back(0); - - std::wstring utf16 = UTF8ToUTF16(std::string_view((const char*)input.data(), input.size() - 1)); - - static constexpr std::pair CJK_RANGE{ 0x4E00, 0x9FAF }; - - std::vector bitSet(CJK_RANGE.second - CJK_RANGE.first + 1); - for (wchar_t character : utf16) { - if (character < CJK_RANGE.first || character > CJK_RANGE.second) { - continue; - } - - bitSet[character - CJK_RANGE.first] = true; - } - - std::vector index; - int prevIdx = 0; - for (int i = 0; i < CJK_RANGE.second - CJK_RANGE.first + 1; ++i) { - if (bitSet[i]) { - index.push_back(uint16_t(i - prevIdx)); - prevIdx = i; - } - } - - if (index.empty()) { - return 0; - } - - std::string out = std::to_string(index[0]); - for (int i = 1; i < index.size(); ++i) { - out += ','; - out += std::to_string(index[i]); - } - - std::cout << out; -} diff --git a/tools/CJKCharacterSetForImGui/input.txt b/tools/CJKCharsetForImGui/characters.txt similarity index 100% rename from tools/CJKCharacterSetForImGui/input.txt rename to tools/CJKCharsetForImGui/characters.txt diff --git a/tools/CJKCharsetForImGui/cjk_charset_for_imgui.py b/tools/CJKCharsetForImGui/cjk_charset_for_imgui.py new file mode 100644 index 000000000..524e6257b --- /dev/null +++ b/tools/CJKCharsetForImGui/cjk_charset_for_imgui.py @@ -0,0 +1,52 @@ +""" +导出供 ImGui 使用的字符表,格式为 https://github.com/ocornut/imgui/blob/bcfc1ad8f63997751a7269788511157ed872da2c/imgui_draw.cpp#L2883 +""" + +import os + +os.chdir(os.path.dirname(__file__)) + +with open("characters.txt", "r", encoding="utf-8") as input: + characters = input.read() + +CJK_RANGE = (0x4E00, 0x9FAF) +codePoints = [False] * (CJK_RANGE[1] - CJK_RANGE[0] + 1) + +# 将所有码位记录到表中 +for char in characters: + codePoint = ord(char) + + if codePoint < CJK_RANGE[0] or codePoint > CJK_RANGE[1]: + continue + + codePoints[codePoint - CJK_RANGE[0]] = True + +# 计算每个码位和前一个的距离 +offsets = list() +prevIdx = 0 +for i in range(0, len(codePoints)): + if codePoints[i]: + offsets.append(i - prevIdx) + prevIdx = i + + +# 分行并确保每行以逗号结尾 +def wrapText(str: str, width: int): + result = "" + + cur = 0 + while cur + width < len(str): + for i in range(width, 1, -1): + if str[cur + i - 1] == ",": + result += str[cur : cur + i] + result += "\n" + + cur += i + break + else: + raise Exception("分行失败") + + result += str[cur:] + return result + +print(wrapText(",".join(map(lambda idx: str(idx), offsets)), 141)) From 8a4a6310706b8a0668db8d9c50aaa7eb9fb05e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 18:35:43 +0800 Subject: [PATCH 38/70] =?UTF-8?q?chore:=20=E5=93=88=E5=B8=8C=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8D=E5=86=8D=E5=8C=85=E5=90=AB=E6=8D=A2=E8=A1=8C?= =?UTF-8?q?=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_ConanDeps/build_conan_deps.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_ConanDeps/build_conan_deps.py b/src/_ConanDeps/build_conan_deps.py index a3517c26c..d477cc310 100644 --- a/src/_ConanDeps/build_conan_deps.py +++ b/src/_ConanDeps/build_conan_deps.py @@ -29,7 +29,7 @@ hashFilePath = f"..\\..\\.conan\\{project}\\{platform}_{configuration}_hash.txt" try: with open(hashFilePath, "r") as hashFile: - if hashFile.read(len(hash)) == hash: + if hashFile.read() == hash: # 哈希未变化 continue except: @@ -52,7 +52,7 @@ # 更新哈希文件 with open(hashFilePath, "w") as hashFile: - print(hash, file=hashFile) + hashFile.write(hash) if not anyProjectToBuild: print("Conan 依赖已是最新", flush=True) From e196986775e4ac1ad610e4124619a806df0f3815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:28:40 +0800 Subject: [PATCH 39/70] =?UTF-8?q?chore:=20=E6=B8=85=E7=90=86=20MPVHookText?= =?UTF-8?q?ureParser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 3 - src/Common.Post.props | 3 + HybridCRT.props => src/HybridCRT.props | 0 .../MPVHookTextureParser.cpp | 29 +++---- .../MPVHookTextureParser.sln | 4 +- .../MPVHookTextureParser.vcxproj | 79 +------------------ tools/MPVHookTextureParser/packages.config | 4 +- 7 files changed, 26 insertions(+), 96 deletions(-) rename HybridCRT.props => src/HybridCRT.props (100%) diff --git a/Directory.Build.props b/Directory.Build.props index c5fcba15e..fbf631c63 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,8 +1,5 @@ - - - stdcpp20 diff --git a/src/Common.Post.props b/src/Common.Post.props index 2dac9b7f9..e6a4e2b65 100644 --- a/src/Common.Post.props +++ b/src/Common.Post.props @@ -55,6 +55,9 @@ true + + + diff --git a/HybridCRT.props b/src/HybridCRT.props similarity index 100% rename from HybridCRT.props rename to src/HybridCRT.props diff --git a/tools/MPVHookTextureParser/MPVHookTextureParser.cpp b/tools/MPVHookTextureParser/MPVHookTextureParser.cpp index 34bbba03a..a055bf28b 100644 --- a/tools/MPVHookTextureParser/MPVHookTextureParser.cpp +++ b/tools/MPVHookTextureParser/MPVHookTextureParser.cpp @@ -1,4 +1,4 @@ -// MPVHookTextureParser.cpp : ļ "main" ִнڴ˴ʼ +// MPVHookTextureParser.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #define NOMINMAX @@ -10,7 +10,7 @@ #include -std::wstring UTF8ToUTF16(std::string_view str) { +static std::wstring UTF8ToUTF16(std::string_view str) noexcept { int convertResult = MultiByteToWideChar(CP_ACP, 0, str.data(), (int)str.size(), nullptr, 0); if (convertResult <= 0) { assert(false); @@ -27,7 +27,7 @@ std::wstring UTF8ToUTF16(std::string_view str) { return std::wstring(r.begin(), r.begin() + convertResult); } -BYTE ResolveHex(char c) { +static BYTE ResolveHex(char c) noexcept { if (c >= '0' && c <= '9') { return c - '0'; } else if (c >= 'a' && c <= 'f') { @@ -39,8 +39,10 @@ BYTE ResolveHex(char c) { int main(int argc, char* argv[]) { + SetConsoleOutputCP(CP_UTF8); + if (argc != 3) { - std::cout << "Ƿ" << std::endl; + std::wcout << "非法参数" << std::endl; return 1; } @@ -49,7 +51,7 @@ int main(int argc, char* argv[]) { std::ifstream ifs(inFile); if (!ifs) { - std::cout << "" << inFile << "ʧ" << std::endl; + std::wcout << L"打开" << inFile << L"失败" << std::endl; return 1; } @@ -60,29 +62,29 @@ int main(int argc, char* argv[]) { std::vector data(width * height * 4); for (size_t i = 0; i < data.size(); ++i) { - // 32 λ + // 解析 32 位浮点数 union { UINT i; FLOAT f; } binary{}; for (int j = 0; j < 4; ++j) { - char c1 = ifs.get(); - char c2 = ifs.get(); + char c1 = (char)ifs.get(); + char c2 = (char)ifs.get(); if (!ifs) { - std::cout << "Ƿļʽ" << std::endl; + std::cout << "非法的文件格式" << std::endl; return 1; } binary.i |= ((ResolveHex(c1) << 4) + ResolveHex(c2)) << (j * 8); } - // תΪ뾫ȸ + // 转换为半精度浮点数 data[i] = DirectX::PackedVector::XMConvertFloatToHalf(binary.f); } - // DDS + // 保存 DDS DirectX::Image img{}; img.width = width; img.height = height; @@ -93,11 +95,10 @@ int main(int argc, char* argv[]) { HRESULT hr = DirectX::SaveToDDSFile(img, DirectX::DDS_FLAGS_NONE, UTF8ToUTF16(outFile).c_str()); if (FAILED(hr)) { - std::cout << " DDS ʧ"; + std::cout << "保存 DDS 失败"; return 1; } - std::cout << " " << outFile << std::endl; + std::cout << "已生成 " << outFile << std::endl; return 0; } - diff --git a/tools/MPVHookTextureParser/MPVHookTextureParser.sln b/tools/MPVHookTextureParser/MPVHookTextureParser.sln index ffca3e8ac..c928fd0b7 100644 --- a/tools/MPVHookTextureParser/MPVHookTextureParser.sln +++ b/tools/MPVHookTextureParser/MPVHookTextureParser.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31729.503 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34202.233 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MPVHookTextureParser", "MPVHookTextureParser.vcxproj", "{370F1793-35B8-4429-B051-8A6040BFE8E4}" EndProject diff --git a/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj b/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj index 167d8faf9..6e2d5540a 100644 --- a/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj +++ b/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj @@ -1,14 +1,6 @@ - - Debug - Win32 - - - Release - Win32 - Debug x64 @@ -26,19 +18,6 @@ 10.0 - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - Application true @@ -57,12 +36,6 @@ - - - - - - @@ -70,12 +43,6 @@ - - true - - - false - true $(SolutionDir) @@ -84,42 +51,9 @@ false $(SolutionDir) - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - Level3 - true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp17 - stdc17 Console @@ -128,14 +62,9 @@ - Level3 true true - true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpp17 - stdc17 Console @@ -152,14 +81,14 @@ - - + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - + + \ No newline at end of file diff --git a/tools/MPVHookTextureParser/packages.config b/tools/MPVHookTextureParser/packages.config index b21c16cf4..ed8a951ff 100644 --- a/tools/MPVHookTextureParser/packages.config +++ b/tools/MPVHookTextureParser/packages.config @@ -1,5 +1,5 @@ - + - + \ No newline at end of file From c03bf76f004b2aba2d42c6f025462f072d42dc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= <34770031+Blinue@users.noreply.github.com> Date: Sun, 15 Oct 2023 19:35:54 +0800 Subject: [PATCH 40/70] =?UTF-8?q?chore:=20=E6=B7=BB=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 1 + 1 file changed, 1 insertion(+) diff --git a/Directory.Build.props b/Directory.Build.props index fbf631c63..ee002f86b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,6 +12,7 @@ Level4 4251 + From 4192b16572d4be271b87d230233d6012e3a35b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Mon, 16 Oct 2023 10:20:06 +0800 Subject: [PATCH 41/70] =?UTF-8?q?chore:=20Conan=20=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=20C++17=20=E7=BC=96=E8=AF=91=20muparser=20?= =?UTF-8?q?=E4=B8=8D=E6=94=AF=E6=8C=81=20C++20=EF=BC=8C=E8=A7=81=20https:/?= =?UTF-8?q?/github.com/conan-io/conan-center-index/issues/17356?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/_ConanDeps/conanprofile.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_ConanDeps/conanprofile.txt b/src/_ConanDeps/conanprofile.txt index a8f025d5a..de8851c8c 100644 --- a/src/_ConanDeps/conanprofile.txt +++ b/src/_ConanDeps/conanprofile.txt @@ -1,5 +1,6 @@ [settings] compiler=msvc -compiler.runtime=static compiler.version=193 +compiler.runtime=static +compiler.cppstd=17 os=Windows From 41eeaf481705c4fca1cff7c4ad32c1df7ee896b7 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:35:25 +0800 Subject: [PATCH 42/70] =?UTF-8?q?=E5=B0=86=20Magpie.Core=20=E9=9D=99?= =?UTF-8?q?=E6=80=81=E9=93=BE=E6=8E=A5=E8=BF=9B=20Magpie.App=20(#735)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: Magpie.Core 改成静态链接 * chore: 修复编译错误 * chore: 删除多余配置 * chore: 清理项目文件 --- src/Common.Post.props | 5 ----- src/Magpie.App/Magpie.App.vcxproj | 1 + src/Magpie.App/conanfile.txt | 3 +++ src/Magpie.Core/DllMain.cpp | 26 -------------------------- src/Magpie.Core/EffectCompiler.h | 3 +-- src/Magpie.Core/ExportHelper.h | 7 ------- src/Magpie.Core/LoggerHelper.h | 3 +-- src/Magpie.Core/MagRuntime.h | 3 +-- src/Magpie.Core/Magpie.Core.vcxproj | 14 ++------------ src/Magpie.Core/conanfile.txt | 13 ------------- src/Magpie/Magpie.vcxproj | 5 +---- src/Magpie/XamlApp.cpp | 2 -- 12 files changed, 10 insertions(+), 75 deletions(-) delete mode 100644 src/Magpie.Core/DllMain.cpp delete mode 100644 src/Magpie.Core/ExportHelper.h delete mode 100644 src/Magpie.Core/conanfile.txt diff --git a/src/Common.Post.props b/src/Common.Post.props index e6a4e2b65..908b5048d 100644 --- a/src/Common.Post.props +++ b/src/Common.Post.props @@ -58,9 +58,4 @@ - - - - - diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index 06bfa9b5c..e211c5f2b 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -45,6 +45,7 @@ + diff --git a/src/Magpie.App/conanfile.txt b/src/Magpie.App/conanfile.txt index 039b3c6fc..7938c0351 100644 --- a/src/Magpie.App/conanfile.txt +++ b/src/Magpie.App/conanfile.txt @@ -4,6 +4,9 @@ spdlog/1.12.0 parallel-hashmap/1.37 rapidjson/cci.20220822 kuba-zip/0.2.6 +muparser/2.3.4 +yas/7.1.0 +imgui/1.89.9 [generators] MSBuildDeps diff --git a/src/Magpie.Core/DllMain.cpp b/src/Magpie.Core/DllMain.cpp deleted file mode 100644 index c4f85f7ba..000000000 --- a/src/Magpie.Core/DllMain.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2021 - present, Liu Xu -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - - -#include "pch.h" - - -BOOL APIENTRY DllMain( - HMODULE /*hModule*/, - DWORD /*ul_reason_for_call*/, - LPVOID /*lpReserved*/ -) { - return TRUE; -} diff --git a/src/Magpie.Core/EffectCompiler.h b/src/Magpie.Core/EffectCompiler.h index c4640ab07..387111a80 100644 --- a/src/Magpie.Core/EffectCompiler.h +++ b/src/Magpie.Core/EffectCompiler.h @@ -1,5 +1,4 @@ #pragma once -#include "ExportHelper.h" #include namespace Magpie::Core { @@ -14,7 +13,7 @@ struct EffectCompilerFlags { static constexpr const uint32_t NoCompile = 0x8; }; -struct API_DECLSPEC EffectCompiler { +struct EffectCompiler { // 调用者需填入 desc 中的 name 和 flags static uint32_t Compile( EffectDesc& desc, diff --git a/src/Magpie.Core/ExportHelper.h b/src/Magpie.Core/ExportHelper.h deleted file mode 100644 index 8e2df2a0c..000000000 --- a/src/Magpie.Core/ExportHelper.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#ifdef MAGPIE_CORE_EXPORTS -#define API_DECLSPEC __declspec(dllexport) -#else -#define API_DECLSPEC __declspec(dllimport) -#endif diff --git a/src/Magpie.Core/LoggerHelper.h b/src/Magpie.Core/LoggerHelper.h index 645d4a794..658d70dd8 100644 --- a/src/Magpie.Core/LoggerHelper.h +++ b/src/Magpie.Core/LoggerHelper.h @@ -1,11 +1,10 @@ #pragma once -#include "ExportHelper.h" class Logger; namespace Magpie::Core { -struct API_DECLSPEC LoggerHelper { +struct LoggerHelper { static void Initialize(Logger& logger); }; diff --git a/src/Magpie.Core/MagRuntime.h b/src/Magpie.Core/MagRuntime.h index b3109acaa..ebc56096b 100644 --- a/src/Magpie.Core/MagRuntime.h +++ b/src/Magpie.Core/MagRuntime.h @@ -1,5 +1,4 @@ #pragma once -#include "ExportHelper.h" #include "WinRTUtils.h" #include #include @@ -9,7 +8,7 @@ namespace Magpie::Core { struct MagOptions; -class API_DECLSPEC MagRuntime { +class MagRuntime { public: MagRuntime(); ~MagRuntime(); diff --git a/src/Magpie.Core/Magpie.Core.vcxproj b/src/Magpie.Core/Magpie.Core.vcxproj index f3029d22b..646620bdc 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj +++ b/src/Magpie.Core/Magpie.Core.vcxproj @@ -13,7 +13,7 @@ - DynamicLibrary + StaticLibrary v143 Unicode @@ -24,16 +24,13 @@ + Fast - MAGPIE_CORE_EXPORTS;_USRDLL;%(PreprocessorDefinitions) - - Windows - @@ -49,7 +46,6 @@ - @@ -75,7 +71,6 @@ - @@ -103,11 +98,6 @@ - - - false - - diff --git a/src/Magpie.Core/conanfile.txt b/src/Magpie.Core/conanfile.txt deleted file mode 100644 index f59e53d05..000000000 --- a/src/Magpie.Core/conanfile.txt +++ /dev/null @@ -1,13 +0,0 @@ -[requires] -fmt/10.1.1 -spdlog/1.12.0 -parallel-hashmap/1.37 -muparser/2.3.4 -yas/7.1.0 -imgui/1.89.9 - -[generators] -MSBuildDeps - -[options] -spdlog/*:no_exceptions=True diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index 184985f6a..6cd6e9917 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -29,17 +29,14 @@ + - - {0e5205ae-dfa9-4cb8-b662-e43cd6512e2a} - - ..\Magpie.Core\include;%(AdditionalIncludeDirectories) Fast diff --git a/src/Magpie/XamlApp.cpp b/src/Magpie/XamlApp.cpp index e8ba1c7b3..742d078be 100644 --- a/src/Magpie/XamlApp.cpp +++ b/src/Magpie/XamlApp.cpp @@ -4,7 +4,6 @@ #include "Win32Utils.h" #include "CommonSharedConstants.h" #include -#include #include "ThemeHelper.h" #include "TrayIconService.h" @@ -207,7 +206,6 @@ void XamlApp::_InitializeLogger() { // 初始化 dll 中的 Logger // Logger 的单例无法在 exe 和 dll 间共享 winrt::Magpie::App::LoggerHelper::Initialize((uint64_t)&logger); - Magpie::Core::LoggerHelper::Initialize(logger); } bool XamlApp::_CreateMainWindow() { From 04d782cbce7d18617f88aaa9c1634c80ed1a0122 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Wed, 25 Oct 2023 00:13:58 +0800 Subject: [PATCH 43/70] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20CI=20=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E7=89=88=E6=9C=AC=20(#737)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 从宏读取版本号 * feat: 用 CI 发布时传入版本号 * feat: 使用 CI 发布版本 * chore: 删除 ci/release.py --- .github/workflows/build.yml | 8 +- .github/workflows/release.yml | 49 +++++ .github/workflows/wiki.yml | 10 +- ci/wiki.py | 6 +- publish.py | 175 +++++++++++++++++- src/Common.Post.props | 2 + src/Magpie.App/AboutViewModel.cpp | 31 +++- src/Magpie.App/AppSettings.cpp | 6 +- src/Magpie.App/AppXReader.cpp | 20 +- src/Magpie.App/AutoStartHelper.cpp | 4 +- src/Magpie.App/EffectsService.cpp | 10 +- src/Magpie.App/HomeViewModel.cpp | 4 +- src/Magpie.App/KeyVisual.cpp | 2 +- src/Magpie.App/Magpie.App.rc | 8 +- src/Magpie.App/Resources.language-en-US.resw | 3 + .../Resources.language-zh-Hans.resw | 3 + src/Magpie.App/ScalingModeEffectItem.cpp | 2 +- src/Magpie.App/UpdateService.cpp | 17 +- src/Magpie.Core/EffectCacheManager.cpp | 4 +- src/Magpie.Core/EffectCompiler.cpp | 4 +- src/Magpie.Core/ImGuiFontsCacheManager.cpp | 2 +- src/Magpie.Core/Magpie.Core.rc | 71 ------- src/Magpie.Core/Magpie.Core.vcxproj | 3 - src/Magpie.Core/Magpie.Core.vcxproj.filters | 16 -- src/Magpie/Magpie.rc | 8 +- src/Magpie/XamlApp.cpp | 7 +- src/Shared/CommonPch.h | 5 + src/Shared/Logger.cpp | 4 +- src/Shared/StrUtils.h | 40 ++-- src/Shared/Version.h | 4 - src/Updater/Updater.rc | 8 +- src/_ConanDeps/build_conan_deps.py | 4 +- tools/BumpVersion.py | 47 ----- 33 files changed, 359 insertions(+), 228 deletions(-) create mode 100644 .github/workflows/release.yml delete mode 100644 src/Magpie.Core/Magpie.Core.rc delete mode 100644 tools/BumpVersion.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2ad69846..5062ca13c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,12 +6,6 @@ on: pull_request: paths: [ '.github/workflows/build.yml', 'Magpie.sln', '*.props', 'publish.py', 'src/**' ] -# env: -# Configuration type to build. -# You can convert this to a build matrix if you need coverage of multiple configuration types. -# https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix -# BUILD_CONFIGURATION: Release - jobs: build: runs-on: windows-latest @@ -42,5 +36,5 @@ jobs: - name: Store build uses: actions/upload-artifact@v3 with: - name: Magpie_dev_${{ steps.hash.outputs.sha_short }} + name: Magpie-dev-${{ steps.hash.outputs.sha_short }} path: ./publish diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..469ec916e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,49 @@ +name: Publish release + +on: + workflow_dispatch: + inputs: + major: + description: 'Major' + required: true + type: number + minor: + description: 'Minor' + required: true + type: number + patch: + description: 'Patch' + required: true + type: number + tag: + description: 'Tag' + required: false + type: string +jobs: + release: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v3 + + - uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Setup Conan + run: pip install conan + + - name: Load Conan cache + uses: actions/cache@v3 + with: + path: ~/.conan2/p + key: ${{ runner.os }}-conan-${{ hashFiles('src/**/conanfile.txt') }} + + - name: Publish release + run: python publish.py + env: + MAJOR: ${{ inputs.major }} + MINOR: ${{ inputs.minor }} + PATCH: ${{ inputs.patch }} + TAG: ${{ inputs.tag }} + ACCESS_TOKEN: ${{ secrets.CONTENTS_ACCESS_TOKEN }} diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml index 587463285..b9846e18a 100644 --- a/.github/workflows/wiki.yml +++ b/.github/workflows/wiki.yml @@ -1,21 +1,15 @@ -name: Publish Wiki +name: Publish wiki -# Controls when the workflow will run on: - # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ main ] paths: [ '.github/workflows/wiki.yml', 'docs/**', 'ci/wiki.py' ] -# A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: publish: - # The type of runner that the job will run on runs-on: windows-latest - # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v3 - uses: actions/setup-python@v4 @@ -25,4 +19,4 @@ jobs: - name: Upload documentations to wiki run: python ci/wiki.py env: - GH_PERSONAL_ACCESS_TOKEN: ${{ secrets.GH_PERSONAL_ACCESS_TOKEN }} + ACCESS_TOKEN: ${{ secrets.CONTENTS_ACCESS_TOKEN }} diff --git a/ci/wiki.py b/ci/wiki.py index 87bb99aad..b58b1caf6 100644 --- a/ci/wiki.py +++ b/ci/wiki.py @@ -14,11 +14,11 @@ except: pass -if not "GH_PERSONAL_ACCESS_TOKEN" in os.environ: - raise Exception("未找到环境变量 GH_PERSONAL_ACCESS_TOKEN") +if not "ACCESS_TOKEN" in os.environ: + raise Exception("未找到环境变量 ACCESS_TOKEN") wikiRepoUrl = os.path.expandvars( - "https://${GH_PERSONAL_ACCESS_TOKEN}@github.com/${GITHUB_REPOSITORY}.wiki.git" + "https://${ACCESS_TOKEN}@github.com/${GITHUB_REPOSITORY}.wiki.git" ) # 创建临时目录 diff --git a/publish.py b/publish.py index f777e56c4..d1043d083 100644 --- a/publish.py +++ b/publish.py @@ -5,15 +5,43 @@ import shutil from xml.etree import ElementTree +majorVersion = None try: # https://docs.github.com/en/actions/learn-github-actions/variables if os.environ["GITHUB_ACTIONS"].lower() == "true": # 不知为何在 Github Actions 中运行时默认编码为 ANSI,并且 print 需刷新流才能正常显示 for stream in [sys.stdout, sys.stderr]: stream.reconfigure(encoding="utf-8") + + # 存在 MAJOR 环境变量则发布新版本 + majorVersion = os.environ["MAJOR"] except: pass +if majorVersion != None: + import re + import hashlib + import json + + # 使用第三方库 requests 发送 HTTP 请求,它是 Conan 的依赖项,无需单独安装 + import requests + + minorVersion = os.environ["MINOR"] + patchVersion = os.environ["PATCH"] + + tag = "" + try: + tag = os.environ["TAG"] + except: + pass + + if tag == "": + tag = f"v{majorVersion}.{minorVersion}.{patchVersion}" + + githubAccessToken = os.environ["ACCESS_TOKEN"] + repo = os.environ["GITHUB_REPOSITORY"] + actor = os.environ["GITHUB_ACTOR"] + ##################################################################### # # 使用 vswhere 查找 msbuild @@ -42,8 +70,46 @@ os.chdir(os.path.dirname(__file__)) +p = subprocess.run("git rev-parse --short HEAD", capture_output=True) +commit_id = str(p.stdout, encoding="utf-8")[0:-1] + +if majorVersion != None: + version_props = f";MajorVersion={majorVersion};MinorVersion={minorVersion};PatchVersion={patchVersion};VersionTag={tag}" + + # 更新 RC 文件中的版本号 + version = f"{majorVersion}.{minorVersion}.{patchVersion}.0" + version_comma = version.replace(".", ",") + for project in os.listdir("src"): + rcPath = f"src\\{project}\\{project}.rc" + if not os.access(rcPath, os.R_OK | os.W_OK): + continue + + with open(rcPath, mode="r+", encoding="utf-8") as f: + src = f.read() + + src = re.sub( + r"FILEVERSION .*?\n", "FILEVERSION " + version_comma + "\n", src + ) + src = re.sub( + r"PRODUCTVERSION .*?\n", "PRODUCTVERSION " + version_comma + "\n", src + ) + src = re.sub( + r'"FileVersion", *?".*?"\n', '"FileVersion", "' + version + '"\n', src + ) + src = re.sub( + r'"ProductVersion", *?".*?"\n', + '"ProductVersion", "' + version + '"\n', + src, + ) + + f.seek(0) + f.truncate() + f.write(src) +else: + version_props = "" + p = subprocess.run( - f'"{msbuildPath}" -restore -p:RestorePackagesConfig=true;Configuration=Release;Platform=x64;OutDir={os.getcwd()}\\publish\\ Magpie.sln' + f'"{msbuildPath}" -restore -p:RestorePackagesConfig=true;Configuration=Release;Platform=x64;OutDir={os.getcwd()}\\publish\\;CommitId={commit_id}{version_props} Magpie.sln' ) if p.returncode != 0: raise Exception("编译失败") @@ -165,3 +231,110 @@ def remove_folder(folder): os.remove("priconfig.xml") print("已修剪 resources.pri", flush=True) + +##################################################################### +# +# 发布 +# +##################################################################### + +if majorVersion != None: + os.chdir("..") + + subprocess.run("git config user.name " + actor) + subprocess.run(f"git config user.email {actor}@users.noreply.github.com") + + subprocess.run( + f"git remote set-url origin https://{githubAccessToken}@github.com/{repo}.git" + ) + + # 打标签 + if subprocess.run(f"git tag -a {tag} -m {tag}").returncode != 0: + raise Exception("打标签失败") + + if subprocess.run("git push origin " + tag).returncode != 0: + raise Exception("推送标签失败") + + print("已创建标签 " + tag, flush=True) + + # 打包成 zip + pkgName = "Magpie-" + tag + "-x64" + shutil.make_archive(pkgName, "zip", "publish") + pkgName += ".zip" + + # 发布 release + headers = { + "Accept": "application/vnd.github+json", + "Authorization": "Bearer " + githubAccessToken, + "X-GitHub-Api-Version": "2022-11-28", + } + response = requests.post( + f"https://api.github.com/repos/{repo}/releases", + json={ + "tag_name": tag, + "name": tag, + "generate_release_notes": True, + "discussion_category_name": "Announcements", + }, + headers=headers, + ) + if not response.ok: + raise Exception("发布失败") + + upload_url = response.json()["upload_url"] + upload_url = upload_url[: upload_url.find("{")] + "?name=" + pkgName + + # 上传资产 + response = requests.post( + upload_url, + files={pkgName: open(pkgName, "rb")}, + headers=headers, + ) + if not response.ok: + raise Exception("上传失败") + + print("已发布 " + tag, flush=True) + + # 更新 version.json + # 此步应在发布版本之后,因为程序使用 version.json 检查更新 + + # 资产上传后会被 Github 修改,我们应计算修改后的哈希值 + response = requests.get( + response.json()["browser_download_url"], + ) + if not response.ok: + raise Exception("下载失败") + + hasher = hashlib.md5() + for chunk in response.iter_content(chunk_size=8192): + hasher.update(chunk) + + # 丢弃当前修改并更新到最新,防止编译时有新的提交 + subprocess.run("git checkout -f") + subprocess.run("git pull") + + with open("version.json", "w", encoding="utf-8") as f: + json.dump( + { + "version": f"{majorVersion}.{minorVersion},{patchVersion}", + "tag": tag, + "binary": { + "x64": { + "url": f"https://github.com/{repo}/releases/download/{tag}/{pkgName}", + "hash": hasher.hexdigest(), + } + }, + }, + f, + indent=4, + ) + + # 提交对 version.json 的更改 + if subprocess.run("git add version.json").returncode != 0: + raise Exception("git add 失败") + + if subprocess.run('git commit -m "Update version.json"').returncode != 0: + raise Exception("git commit 失败") + + if subprocess.run("git push").returncode != 0: + raise Exception("git push 失败") diff --git a/src/Common.Post.props b/src/Common.Post.props index 908b5048d..4f2ad80d4 100644 --- a/src/Common.Post.props +++ b/src/Common.Post.props @@ -28,6 +28,8 @@ pch.h $(IntDir)pch.pch _WINDOWS;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;WINRT_NO_MODULE_LOCK;NOGDICAPMASKS;NOICONS;NOATOM;NOCLIPBOARD;NODRAWTEXT;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;%(PreprocessorDefinitions) + MAGPIE_COMMIT_ID=$(CommitId);%(PreprocessorDefinitions) + MAGPIE_VERSION_MAJOR=$(MajorVersion);MAGPIE_VERSION_MINOR=$(MinorVersion);MAGPIE_VERSION_PATCH=$(PatchVersion);MAGPIE_VERSION_TAG=$(VersionTag);%(PreprocessorDefinitions) /bigobj %(AdditionalOptions) diff --git a/src/Magpie.App/AboutViewModel.cpp b/src/Magpie.App/AboutViewModel.cpp index 4eca520ab..59c8fe4d0 100644 --- a/src/Magpie.App/AboutViewModel.cpp +++ b/src/Magpie.App/AboutViewModel.cpp @@ -57,8 +57,28 @@ AboutViewModel::AboutViewModel() { hstring AboutViewModel::Version() const noexcept { ResourceLoader resourceLoader = ResourceLoader::GetForCurrentView(); - hstring versionStr = resourceLoader.GetString(L"About_Version_Version"); - return versionStr + StrUtils::ConcatW(L" ", MAGPIE_TAG_W + 1, L" | x64"); + return hstring(StrUtils::Concat( + resourceLoader.GetString(L"About_Version_Version"), +#ifdef MAGPIE_VERSION_TAG + L" ", + WIDEN(STRING(MAGPIE_VERSION_TAG)) + 1, +#else + L" dev", +#endif +#ifdef MAGPIE_COMMIT_ID + L" | ", + resourceLoader.GetString(L"About_Version_CommitId"), + L" " WIDEN(STRING(MAGPIE_COMMIT_ID)), +#endif + L" | " +#ifdef _M_X64 + L"x64" +#elif defined(_M_ARM64) + L"ARM64" +#else + static_assert(false, "不支持的架构") +#endif + )); } fire_and_forget AboutViewModel::CheckForUpdates() { @@ -75,6 +95,11 @@ void AboutViewModel::IsCheckForPreviewUpdates(bool value) noexcept { } bool AboutViewModel::IsCheckForUpdatesButtonEnabled() const noexcept { +#ifndef MAGPIE_VERSION_TAG + // 只有正式版本才能检查更新 + return false; +#endif + return !IsCheckingForUpdates() && !IsDownloadingOrLater(); } @@ -203,7 +228,7 @@ Uri AboutViewModel::UpdateReleaseNotesLink() const noexcept { return nullptr; } - return Uri(StrUtils::ConcatW(L"https://github.com/Blinue/Magpie/releases/tag/", + return Uri(StrUtils::Concat(L"https://github.com/Blinue/Magpie/releases/tag/", UpdateService::Get().Tag())); } diff --git a/src/Magpie.App/AppSettings.cpp b/src/Magpie.App/AppSettings.cpp index 3fba276fe..9cf22ee09 100644 --- a/src/Magpie.App/AppSettings.cpp +++ b/src/Magpie.App/AppSettings.cpp @@ -207,7 +207,7 @@ bool AppSettings::Initialize() { // 若程序所在目录存在配置文件则为便携模式 _isPortableMode = Win32Utils::FileExists( - StrUtils::ConcatW(CommonSharedConstants::CONFIG_DIR, CommonSharedConstants::CONFIG_NAME).c_str()); + StrUtils::Concat(CommonSharedConstants::CONFIG_DIR, CommonSharedConstants::CONFIG_NAME).c_str()); _UpdateConfigPath(); logger.Info(StrUtils::Concat("便携模式:", _isPortableMode ? "是" : "否")); @@ -332,7 +332,7 @@ void AppSettings::IsPortableMode(bool value) { if (!value) { // 关闭便携模式需删除本地配置文件 // 不关心是否成功 - DeleteFile(StrUtils::ConcatW(_configDir, CommonSharedConstants::CONFIG_NAME).c_str()); + DeleteFile(StrUtils::Concat(_configDir, CommonSharedConstants::CONFIG_NAME).c_str()); } Logger::Get().Info(value ? "已开启便携模式" : "已关闭便携模式"); @@ -970,7 +970,7 @@ void AppSettings::_UpdateConfigPath() noexcept { wchar_t localAppDataDir[MAX_PATH]; HRESULT hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, localAppDataDir); if (SUCCEEDED(hr)) { - _configDir = StrUtils::ConcatW( + _configDir = StrUtils::Concat( localAppDataDir, localAppDataDir[StrUtils::StrLen(localAppDataDir) - 1] == L'\\' ? L"Magpie\\" : L"\\Magpie\\", CommonSharedConstants::CONFIG_DIR diff --git a/src/Magpie.App/AppXReader.cpp b/src/Magpie.App/AppXReader.cpp index f52ff144f..0345126a2 100644 --- a/src/Magpie.App/AppXReader.cpp +++ b/src/Magpie.App/AppXReader.cpp @@ -55,9 +55,9 @@ static std::wstring ResourceFromPri(std::wstring_view packageFullName, std::wstr // Using Ordinal/OrdinalIgnoreCase since these are used internally if (key.starts_with(L"//")) { - parsed = StrUtils::ConcatW(prefix, key); + parsed = StrUtils::Concat(prefix, key); } else if (key.starts_with(L'/')) { - parsed = StrUtils::ConcatW(prefix, L"//", key); + parsed = StrUtils::Concat(prefix, L"//", key); } else { std::wstring_view lowerCaseKey( lowerCaseResourceReference.begin() + prefix.size(), @@ -65,12 +65,12 @@ static std::wstring ResourceFromPri(std::wstring_view packageFullName, std::wstr ); if (lowerCaseKey.starts_with(L"resources")) { - parsed = StrUtils::ConcatW(prefix, key); + parsed = StrUtils::Concat(prefix, key); } else { - parsed = StrUtils::ConcatW(prefix, L"///resources/", key); + parsed = StrUtils::Concat(prefix, L"///resources/", key); // e.g. for Windows Terminal version >= 1.12 DisplayName and Description resources are not in the 'resources' subtree - parsedFallback = StrUtils::ConcatW(prefix, L"///", key); + parsedFallback = StrUtils::Concat(prefix, L"///", key); } } @@ -317,7 +317,7 @@ std::wstring AppXReader::GetExecutablePath() noexcept { return {}; } - return StrUtils::ConcatW(_packagePath, _executable); + return StrUtils::Concat(_packagePath, _executable); } class CandidateIcon { @@ -650,7 +650,7 @@ std::variant AppXReader::GetIcon( if (_square44x44Logo.find(L'\\') != std::wstring_view::npos) { iconFileName = _packagePath + _square44x44Logo; } else { - iconFileName = StrUtils::ConcatW(_packagePath, L"Assets\\", _square44x44Logo);; + iconFileName = StrUtils::Concat(_packagePath, L"Assets\\", _square44x44Logo);; } size_t delimPos = iconFileName.find_last_of(L'\\'); @@ -666,14 +666,14 @@ std::variant AppXReader::GetIcon( std::wstring_view extension(iconFileName.begin() + extensionPointPos, iconFileName.end()); std::wstring_view iconName(iconFileName.begin() + delimPos + 1, iconFileName.begin() + extensionPointPos); - std::wstring iconNameExt = StrUtils::ConcatW(iconName, extension); + std::wstring iconNameExt = StrUtils::Concat(iconName, extension); std::wregex regex(fmt::format(L"^{}\\.[^\\.]+\\{}$", iconName, extension), std::wregex::nosubs); std::vector candidateIcons; WIN32_FIND_DATA findData{}; - HANDLE hFind = Win32Utils::SafeHandle(FindFirstFileEx(StrUtils::ConcatW(prefix, L"*").c_str(), + HANDLE hFind = Win32Utils::SafeHandle(FindFirstFileEx(StrUtils::Concat(prefix, L"*").c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH)); if (hFind) { do { @@ -704,7 +704,7 @@ std::variant AppXReader::GetIcon( } ); - std::wstring iconPath = StrUtils::ConcatW( + std::wstring iconPath = StrUtils::Concat( std::wstring_view(iconFileName.begin(), iconFileName.begin() + delimPos + 1), it->FileName() ); diff --git a/src/Magpie.App/AutoStartHelper.cpp b/src/Magpie.App/AutoStartHelper.cpp index a37c5dd29..117df2d50 100644 --- a/src/Magpie.App/AutoStartHelper.cpp +++ b/src/Magpie.App/AutoStartHelper.cpp @@ -30,7 +30,7 @@ static constexpr const DWORD USERNAME_LEN = UNLEN + 1; // User Name + '\0' static std::wstring GetTaskName(std::wstring_view userName) { - return StrUtils::ConcatW(L"Autorun for ", userName); + return StrUtils::Concat(L"Autorun for ", userName); } static com_ptr CreateTaskService() { @@ -394,7 +394,7 @@ static std::wstring GetShortcutPath() { return {}; } - shortcutPath = StrUtils::ConcatW(startupDir, L"\\Magpie.lnk"); + shortcutPath = StrUtils::Concat(startupDir, L"\\Magpie.lnk"); CoTaskMemFree(startupDir); return shortcutPath; diff --git a/src/Magpie.App/EffectsService.cpp b/src/Magpie.App/EffectsService.cpp index 76cfa1680..9f21b08f9 100644 --- a/src/Magpie.App/EffectsService.cpp +++ b/src/Magpie.App/EffectsService.cpp @@ -21,7 +21,7 @@ static void ListEffects(std::vector& result, std::wstring_view pre WIN32_FIND_DATA findData{}; HANDLE hFind = Win32Utils::SafeHandle(FindFirstFileEx( - StrUtils::ConcatW(CommonSharedConstants::EFFECTS_DIR, prefix, L"*").c_str(), + StrUtils::Concat(CommonSharedConstants::EFFECTS_DIR, prefix, L"*").c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH)); if (hFind) { do { @@ -30,8 +30,8 @@ static void ListEffects(std::vector& result, std::wstring_view pre continue; } - if (Win32Utils::DirExists(StrUtils::ConcatW(CommonSharedConstants::EFFECTS_DIR, prefix, fileName).c_str())) { - ListEffects(result, StrUtils::ConcatW(prefix, fileName, L"\\")); + if (Win32Utils::DirExists(StrUtils::Concat(CommonSharedConstants::EFFECTS_DIR, prefix, fileName).c_str())) { + ListEffects(result, StrUtils::Concat(prefix, fileName, L"\\")); continue; } @@ -39,7 +39,7 @@ static void ListEffects(std::vector& result, std::wstring_view pre continue; } - result.emplace_back(StrUtils::ConcatW(prefix, fileName.substr(0, fileName.size() - 5))); + result.emplace_back(StrUtils::Concat(prefix, fileName.substr(0, fileName.size() - 5))); } while (FindNextFile(hFind, &findData)); FindClose(hFind); @@ -81,7 +81,7 @@ fire_and_forget EffectsService::StartInitialize() { if (pos == std::wstring::npos) { effect.sortName = StrUtils::UTF8ToUTF16(effectDesc.sortName); } else { - effect.sortName = StrUtils::ConcatW( + effect.sortName = StrUtils::Concat( std::wstring_view(effect.name.c_str(), pos + 1), StrUtils::UTF8ToUTF16(effectDesc.sortName) ); diff --git a/src/Magpie.App/HomeViewModel.cpp b/src/Magpie.App/HomeViewModel.cpp index 69d18596c..920f277ee 100644 --- a/src/Magpie.App/HomeViewModel.cpp +++ b/src/Magpie.App/HomeViewModel.cpp @@ -129,7 +129,7 @@ hstring HomeViewModel::RestoreWndDesc() const noexcept { hstring curWindow = resourceLoader.GetString(L"Home_AutoRestore_CurWindow"); if (title.empty()) { hstring emptyTitle = resourceLoader.GetString(L"Home_AutoRestore_EmptyTitle"); - return hstring(StrUtils::ConcatW(curWindow, L"<", emptyTitle, L">")); + return hstring(StrUtils::Concat(curWindow, L"<", emptyTitle, L">")); } else { return curWindow + title; } @@ -170,7 +170,7 @@ void HomeViewModel::DownloadAndInstall() { } void HomeViewModel::ReleaseNotes() { - std::wstring url = StrUtils::ConcatW( + std::wstring url = StrUtils::Concat( L"https://github.com/Blinue/Magpie/releases/tag/", UpdateService::Get().Tag() ); diff --git a/src/Magpie.App/KeyVisual.cpp b/src/Magpie.App/KeyVisual.cpp index 2eab99420..9418d3dd4 100644 --- a/src/Magpie.App/KeyVisual.cpp +++ b/src/Magpie.App/KeyVisual.cpp @@ -137,7 +137,7 @@ Style KeyVisual::_GetStyleSize(std::wstring_view styleName) const { } return Application::Current().Resources() - .Lookup(box_value(StrUtils::ConcatW(prefix, styleName))) + .Lookup(box_value(StrUtils::Concat(prefix, styleName))) .as(); } diff --git a/src/Magpie.App/Magpie.App.rc b/src/Magpie.App/Magpie.App.rc index f125e3ac9..adb473af6 100644 --- a/src/Magpie.App/Magpie.App.rc +++ b/src/Magpie.App/Magpie.App.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,3,0 - PRODUCTVERSION 0,10,3,0 + FILEVERSION 0,0,0,0 + PRODUCTVERSION 0,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -41,12 +41,12 @@ BEGIN BEGIN BLOCK "000004b0" BEGIN - VALUE "FileVersion", "0.10.3.0" + VALUE "FileVersion", "0.0.0.0" VALUE "InternalName", "Magpie.App.dll" VALUE "LegalCopyright", "Copyright (C) 2023 Liu Xu" VALUE "OriginalFilename", "Magpie.App.dll" VALUE "ProductName", "Magpie" - VALUE "ProductVersion", "0.10.3.0" + VALUE "ProductVersion", "0.0.0.0" END END BLOCK "VarFileInfo" diff --git a/src/Magpie.App/Resources.language-en-US.resw b/src/Magpie.App/Resources.language-en-US.resw index 90b2f25aa..b958130f8 100644 --- a/src/Magpie.App/Resources.language-en-US.resw +++ b/src/Magpie.App/Resources.language-en-US.resw @@ -844,4 +844,7 @@ Scale the foreground window or stop scaling + + Commit + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-zh-Hans.resw b/src/Magpie.App/Resources.language-zh-Hans.resw index 117f20e66..acd65f303 100644 --- a/src/Magpie.App/Resources.language-zh-Hans.resw +++ b/src/Magpie.App/Resources.language-zh-Hans.resw @@ -844,4 +844,7 @@ 缩放前台窗口或停止缩放 + + 提交 + \ No newline at end of file diff --git a/src/Magpie.App/ScalingModeEffectItem.cpp b/src/Magpie.App/ScalingModeEffectItem.cpp index 859797b55..49b275fa9 100644 --- a/src/Magpie.App/ScalingModeEffectItem.cpp +++ b/src/Magpie.App/ScalingModeEffectItem.cpp @@ -29,7 +29,7 @@ ScalingModeEffectItem::ScalingModeEffectItem(uint32_t scalingModeIdx, uint32_t e _parametersViewModel = EffectParametersViewModel(scalingModeIdx, effectIdx); } else { ResourceLoader resourceLoader = ResourceLoader::GetForCurrentView(); - _name = StrUtils::ConcatW( + _name = StrUtils::Concat( resourceLoader.GetString(L"ScalingConfiguration_ScalingModes_Description_UnknownEffect"), L" (", data.name, diff --git a/src/Magpie.App/UpdateService.cpp b/src/Magpie.App/UpdateService.cpp index 89d1481dd..a19c26182 100644 --- a/src/Magpie.App/UpdateService.cpp +++ b/src/Magpie.App/UpdateService.cpp @@ -20,7 +20,20 @@ using namespace Windows::System::Threading; namespace winrt::Magpie::App { +static constexpr Version MAGPIE_VERSION( +#ifdef MAGPIE_VERSION_MAJOR + MAGPIE_VERSION_MAJOR, MAGPIE_VERSION_MINOR, MAGPIE_VERSION_PATCH +#else + 0, 0, 0 +#endif +); + void UpdateService::Initialize() noexcept { +#ifndef MAGPIE_VERSION_TAG + // 只有正式版本才能检查更新 + return; +#endif + _dispatcher = CoreWindow::GetForCurrentThread().Dispatcher(); AppSettings& settings = AppSettings::Get(); @@ -316,8 +329,8 @@ fire_and_forget UpdateService::DownloadAndInstall() { DeleteFile(updatePkg.c_str()); - std::wstring magpieExePath = StrUtils::ConcatW(CommonSharedConstants::UPDATE_DIR, L"Magpie.exe"); - std::wstring updaterExePath = StrUtils::ConcatW(CommonSharedConstants::UPDATE_DIR, L"Updater.exe"); + std::wstring magpieExePath = StrUtils::Concat(CommonSharedConstants::UPDATE_DIR, L"Magpie.exe"); + std::wstring updaterExePath = StrUtils::Concat(CommonSharedConstants::UPDATE_DIR, L"Updater.exe"); if (!Win32Utils::FileExists(magpieExePath.c_str()) || !Win32Utils::FileExists(updaterExePath.c_str())) { Logger::Get().Error("未找到 Magpie.exe 或 Updater.exe"); co_await dispatcher; diff --git a/src/Magpie.Core/EffectCacheManager.cpp b/src/Magpie.Core/EffectCacheManager.cpp index 79d35a821..f94565002 100644 --- a/src/Magpie.Core/EffectCacheManager.cpp +++ b/src/Magpie.Core/EffectCacheManager.cpp @@ -200,7 +200,7 @@ void EffectCacheManager::Save(std::wstring_view effectName, std::wstring_view ha WIN32_FIND_DATA findData{}; HANDLE hFind = Win32Utils::SafeHandle(FindFirstFileEx( - StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR, L"*").c_str(), + StrUtils::Concat(CommonSharedConstants::CACHE_DIR, L"*").c_str(), FindExInfoBasic, &findData, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH)); if (hFind) { do { @@ -215,7 +215,7 @@ void EffectCacheManager::Save(std::wstring_view effectName, std::wstring_view ha continue; } - if (!DeleteFile(StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR, findData.cFileName).c_str())) { + if (!DeleteFile(StrUtils::Concat(CommonSharedConstants::CACHE_DIR, findData.cFileName).c_str())) { Logger::Get().Win32Error(StrUtils::Concat("删除缓存文件 ", StrUtils::UTF16ToUTF8(findData.cFileName), " 失败")); } diff --git a/src/Magpie.Core/EffectCompiler.cpp b/src/Magpie.Core/EffectCompiler.cpp index a4afe34e3..cf8f71b25 100644 --- a/src/Magpie.Core/EffectCompiler.cpp +++ b/src/Magpie.Core/EffectCompiler.cpp @@ -32,7 +32,7 @@ class PassInclude : public ID3DInclude { LPCVOID* ppData, UINT* pBytes ) noexcept override { - std::wstring relativePath = StrUtils::ConcatW(_localDir, StrUtils::UTF8ToUTF16(pFileName)); + std::wstring relativePath = StrUtils::Concat(_localDir, StrUtils::UTF8ToUTF16(pFileName)); std::string file; if (!Win32Utils::ReadTextFile(relativePath.c_str(), file)) { @@ -1543,7 +1543,7 @@ uint32_t EffectCompiler::Compile( bool noCache = noCompile || (flags & EffectCompilerFlags::NoCache); std::wstring effectName = StrUtils::UTF8ToUTF16(desc.name); - std::wstring fileName = StrUtils::ConcatW(CommonSharedConstants::EFFECTS_DIR, effectName, L".hlsl"); + std::wstring fileName = StrUtils::Concat(CommonSharedConstants::EFFECTS_DIR, effectName, L".hlsl"); std::string source; if (!Win32Utils::ReadTextFile(fileName.c_str(), source)) { diff --git a/src/Magpie.Core/ImGuiFontsCacheManager.cpp b/src/Magpie.Core/ImGuiFontsCacheManager.cpp index e2f754d95..c93381fab 100644 --- a/src/Magpie.Core/ImGuiFontsCacheManager.cpp +++ b/src/Magpie.Core/ImGuiFontsCacheManager.cpp @@ -144,7 +144,7 @@ namespace Magpie::Core { static constexpr const uint32_t FONTS_CACHE_VERSION = 1; static std::wstring GetCacheFileName(const std::wstring_view& language) noexcept { - return StrUtils::ConcatW(CommonSharedConstants::CACHE_DIR, L"fonts_", language); + return StrUtils::Concat(CommonSharedConstants::CACHE_DIR, L"fonts_", language); } void ImGuiFontsCacheManager::Save(std::wstring_view language, const ImFontAtlas& fontAltas) noexcept { diff --git a/src/Magpie.Core/Magpie.Core.rc b/src/Magpie.Core/Magpie.Core.rc deleted file mode 100644 index 899be79c9..000000000 --- a/src/Magpie.Core/Magpie.Core.rc +++ /dev/null @@ -1,71 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#pragma code_page(65001) - - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "winres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// 非特定语言 resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD) -LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,3,0 - PRODUCTVERSION 0,10,3,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "FileVersion", "0.10.3.0" - VALUE "InternalName", "Magpie.Core.dll" - VALUE "LegalCopyright", "Copyright (C) 2023 Liu Xu" - VALUE "OriginalFilename", "Magpie.Core.dll" - VALUE "ProductName", "Magpie" - VALUE "ProductVersion", "0.10.3.0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x000, 1200 - END -END - -#endif // 非特定语言 resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED diff --git a/src/Magpie.Core/Magpie.Core.vcxproj b/src/Magpie.Core/Magpie.Core.vcxproj index 646620bdc..1e075af8c 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj +++ b/src/Magpie.Core/Magpie.Core.vcxproj @@ -95,9 +95,6 @@ - - - diff --git a/src/Magpie.Core/Magpie.Core.vcxproj.filters b/src/Magpie.Core/Magpie.Core.vcxproj.filters index cbd551017..31fffeb31 100644 --- a/src/Magpie.Core/Magpie.Core.vcxproj.filters +++ b/src/Magpie.Core/Magpie.Core.vcxproj.filters @@ -10,10 +10,6 @@ {b0bbac79-0e76-436d-bcaa-b725b62d545f} - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - {7ed1757c-3140-42a7-93b3-5bf0171cfa7b} @@ -80,9 +76,6 @@ Helpers - - Helpers - Helpers @@ -99,7 +92,6 @@ - @@ -152,15 +144,7 @@ Overlay - - - 资源文件 - - - - - \ No newline at end of file diff --git a/src/Magpie/Magpie.rc b/src/Magpie/Magpie.rc index eacc50112..6e3269523 100644 --- a/src/Magpie/Magpie.rc +++ b/src/Magpie/Magpie.rc @@ -62,8 +62,8 @@ IDI_APP ICON "Magpie.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,3,0 - PRODUCTVERSION 0,10,3,0 + FILEVERSION 0,0,0,0 + PRODUCTVERSION 0,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -78,12 +78,12 @@ BEGIN BEGIN BLOCK "000004b0" BEGIN - VALUE "FileVersion", "0.10.3.0" + VALUE "FileVersion", "0.0.0.0" VALUE "InternalName", "Magpie.exe" VALUE "LegalCopyright", "Copyright (C) 2023 Liu Xu" VALUE "OriginalFilename", "Magpie.exe" VALUE "ProductName", "Magpie" - VALUE "ProductVersion", "0.10.3.0" + VALUE "ProductVersion", "0.0.0.0" END END BLOCK "VarFileInfo" diff --git a/src/Magpie/XamlApp.cpp b/src/Magpie/XamlApp.cpp index 742d078be..5ab9c0804 100644 --- a/src/Magpie/XamlApp.cpp +++ b/src/Magpie/XamlApp.cpp @@ -27,7 +27,12 @@ bool XamlApp::Initialize(HINSTANCE hInstance, const wchar_t* arguments) { _InitializeLogger(); Logger::Get().Info(fmt::format("程序启动\n\t版本:{}\n\t管理员:{}", - MAGPIE_TAG, Win32Utils::IsProcessElevated() ? "是" : "否")); +#ifdef MAGPIE_VERSION_TAG + STRING(MAGPIE_VERSION_TAG) +#else + "dev" +#endif + , Win32Utils::IsProcessElevated() ? "是" : "否")); if (!_CheckSingleInstance()) { Logger::Get().Info("已经有一个实例正在运行"); diff --git a/src/Shared/CommonPch.h b/src/Shared/CommonPch.h index ccfdf98f8..cba5da256 100644 --- a/src/Shared/CommonPch.h +++ b/src/Shared/CommonPch.h @@ -80,3 +80,8 @@ using winrt::operator co_await; FlagsVar &= ~FlagBit; \ } \ } + +#define _WIDEN_HELPER(x) L ## x +#define WIDEN(x) _WIDEN_HELPER(x) +#define _STRING_HELPER(x) #x +#define STRING(x) _STRING_HELPER(x) diff --git a/src/Shared/Logger.cpp b/src/Shared/Logger.cpp index e369decc2..d702850a7 100644 --- a/src/Shared/Logger.cpp +++ b/src/Shared/Logger.cpp @@ -50,9 +50,9 @@ void Logger::_Log(spdlog::level::level_enum logLevel, std::string_view msg, cons if (logLevel >= spdlog::level::warn) { // 警告或更高等级的日志也记录到调试器(VS 中的“即时窗口”) if (msg.back() == '\n') { - OutputDebugString(StrUtils::ConcatW(L"[LOG] ", StrUtils::UTF8ToUTF16(msg)).c_str()); + OutputDebugString(StrUtils::Concat(L"[LOG] ", StrUtils::UTF8ToUTF16(msg)).c_str()); } else { - OutputDebugString(StrUtils::ConcatW(L"[LOG] ", StrUtils::UTF8ToUTF16(msg), L"\n").c_str()); + OutputDebugString(StrUtils::Concat(L"[LOG] ", StrUtils::UTF8ToUTF16(msg), L"\n").c_str()); } } diff --git a/src/Shared/StrUtils.h b/src/Shared/StrUtils.h index a21fcf171..da2d4f97c 100644 --- a/src/Shared/StrUtils.h +++ b/src/Shared/StrUtils.h @@ -161,14 +161,10 @@ struct StrUtils { return std::char_traits::length(str); } - template - static std::string Concat(const std::string_view& s1, const std::string_view& s2, const AV&... args) noexcept { - return _Concat(s1, s2, static_cast(args)...); - } - - template - static std::wstring ConcatW(const std::wstring_view& s1, const std::wstring_view& s2, const AV&... args) noexcept { - return _Concat(s1, s2, static_cast(args)...); + template, T1>, char, wchar_t>> + static std::basic_string Concat(T1&& s1, T2&& s2, AV&&... args) noexcept { + return _Concat(std::forward(s1), std::forward(s2), std::forward(args)...); } private: @@ -222,21 +218,31 @@ struct StrUtils { return result; } - template + template static std::basic_string _Concat( - const std::basic_string_view& s1, - const std::basic_string_view& s2, - const std::basic_string_view& s3, - const std::basic_string_view& s4, - const std::basic_string_view& s5, - const AV&... args + T1&& s1, + T2&& s2, + T3&& s3, + T4&& s4, + T5&& s5, + T6&& s6, + AV&&... args ) noexcept { - return _Concat({ s1, s2, s3, s4, s5, static_cast&>(args)... }); + return _ConcatHelper({ + std::forward(s1), + std::forward(s2), + std::forward(s3), + std::forward(s4), + std::forward(s5), + std::forward(s6), + std::forward(args)... + }); } template - static std::basic_string _Concat(std::initializer_list&> args) noexcept { + static std::basic_string _ConcatHelper(std::initializer_list> args) noexcept { std::basic_string result; + size_t size = 0; for (const std::basic_string_view& s : args) { size += s.size(); diff --git a/src/Shared/Version.h b/src/Shared/Version.h index 06750377c..f2802d125 100644 --- a/src/Shared/Version.h +++ b/src/Shared/Version.h @@ -21,7 +21,3 @@ struct Version { uint32_t minor = 0; uint32_t patch = 0; }; - -constexpr inline Version MAGPIE_VERSION(0, 10, 3); -constexpr inline const char* MAGPIE_TAG = "v0.10.3"; -constexpr inline const wchar_t* MAGPIE_TAG_W = L"v0.10.3"; diff --git a/src/Updater/Updater.rc b/src/Updater/Updater.rc index 3c530a23d..5b316b547 100644 --- a/src/Updater/Updater.rc +++ b/src/Updater/Updater.rc @@ -67,8 +67,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,3,0 - PRODUCTVERSION 0,10,3,0 + FILEVERSION 0,0,0,0 + PRODUCTVERSION 0,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -83,12 +83,12 @@ BEGIN BEGIN BLOCK "000004b0" BEGIN - VALUE "FileVersion", "0.10.3.0" + VALUE "FileVersion", "0.0.0.0" VALUE "InternalName", "Updater.exe" VALUE "LegalCopyright", "Copyright (C) 2023 Liu Xu" VALUE "OriginalFilename", "Updater.exe" VALUE "ProductName", "Magpie" - VALUE "ProductVersion", "0.10.3.0" + VALUE "ProductVersion", "0.0.0.0" END END BLOCK "VarFileInfo" diff --git a/src/_ConanDeps/build_conan_deps.py b/src/_ConanDeps/build_conan_deps.py index d477cc310..3c2b324e6 100644 --- a/src/_ConanDeps/build_conan_deps.py +++ b/src/_ConanDeps/build_conan_deps.py @@ -22,8 +22,8 @@ conanfilePath = f"..\\{project}\\conanfile.txt" try: with open(conanfilePath, "rb") as conanfile: - hash = hashlib.file_digest(conanfile, hashlib.sha256).hexdigest() - except: + hash = hashlib.sha256(conanfile.read()).hexdigest() + except FileNotFoundError: continue hashFilePath = f"..\\..\\.conan\\{project}\\{platform}_{configuration}_hash.txt" diff --git a/tools/BumpVersion.py b/tools/BumpVersion.py deleted file mode 100644 index 6d5201a73..000000000 --- a/tools/BumpVersion.py +++ /dev/null @@ -1,47 +0,0 @@ -""" -用于更新版本号 -使用方式: python BumpVersion.py 1.0.0 -可选的可以指定 tag: python BumpVersion.py 1.0.100 1.1.0-preview1 -""" - -import sys -import re - -assert len(sys.argv) in [2, 3] and len(sys.argv[1]) > 0 - -versionNumbers = list(map(lambda s: int(s), sys.argv[1].split("."))) -versionNumbers.extend([0, 0, 0]) - -srcDir = "..\\src\\" - -# 更新 RC 文件 -version = "%d.%d.%d.%d" % tuple(versionNumbers[0:4]) -versionComma = version.replace(".", ",") -for project in ["Magpie", "Magpie.Core", "Magpie.App", "Updater"]: - with open("{}{}\\{}.rc".format(srcDir, project, project), mode="r+", encoding="utf8") as f: - src = f.read() - - src = re.sub(r"FILEVERSION .*?\n", "FILEVERSION " + versionComma + "\n", src) - src = re.sub(r"PRODUCTVERSION .*?\n", "PRODUCTVERSION " + versionComma + "\n", src) - src = re.sub(r'"FileVersion", *?".*?"\n', '"FileVersion", "' + version + '"\n', src) - src = re.sub(r'"ProductVersion", *?".*?"\n', '"ProductVersion", "' + version + '"\n', src) - - f.seek(0) - f.truncate() - f.write(src) - -# 更新 Version.h -with open(srcDir + "Shared\\Version.h", mode="r+", encoding="utf8") as f: - src = f.read() - src = re.sub(r"MAGPIE_VERSION\(.*?\)", "MAGPIE_VERSION(%d, %d, %d)" % tuple(versionNumbers[0:3]), src) - - if len(sys.argv) == 3 and len(sys.argv[2]) > 0: - versionStr = sys.argv[2] - else: - versionStr = "v%d.%d.%d" % tuple(versionNumbers[0:3]) - src = re.sub(r'MAGPIE_TAG *?= *?".*?";', 'MAGPIE_TAG = "' + versionStr + '";', src) - src = re.sub(r'MAGPIE_TAG_W *?= *?L".*?";', 'MAGPIE_TAG_W = L"' + versionStr + '";', src) - - f.seek(0) - f.truncate() - f.write(src) From 1ffb9adece0d92a02a422bb5444822ee01ee5cbb Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 31 Oct 2023 08:10:07 +0100 Subject: [PATCH 44/70] Translations update from Hosted Weblate (#741) * Translated using Weblate (Japanese) Currently translated at 100.0% (243 of 243 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ja/ * Translated using Weblate (Russian) Currently translated at 100.0% (243 of 243 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ru/ --------- Co-authored-by: animeojisan Co-authored-by: Artjom Jemeljanov --- src/Magpie.App/Resources.language-ja.resw | 3 + src/Magpie.App/Resources.language-ru.resw | 217 +++++++++++----------- 2 files changed, 113 insertions(+), 107 deletions(-) diff --git a/src/Magpie.App/Resources.language-ja.resw b/src/Magpie.App/Resources.language-ja.resw index bd55f79f7..948266941 100644 --- a/src/Magpie.App/Resources.language-ja.resw +++ b/src/Magpie.App/Resources.language-ja.resw @@ -844,4 +844,7 @@ 前面ウィンドウをスケーリング、またはスケーリングを停止 + + コミット + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-ru.resw b/src/Magpie.App/Resources.language-ru.resw index 60eed46cb..2d5a1752a 100644 --- a/src/Magpie.App/Resources.language-ru.resw +++ b/src/Magpie.App/Resources.language-ru.resw @@ -121,7 +121,7 @@ О программе
- Включение + Активация Очистить @@ -148,7 +148,7 @@ Переименовать - Заполнить + Заполнение Установка @@ -157,10 +157,10 @@ Расширенные - Указатель + Курсор - Множитель увеличения + Множитель масштабирования Пользовательский @@ -169,7 +169,7 @@ Не удалось прочитать файл настроек - Выход + Выйти Главное окно @@ -181,13 +181,13 @@ Перезапустить Magpie - Автоувеличение если окно на переднем плане + Автоматическое масштабирование при возвращении окна на передний план - Автовосстановление + Автоматическое восстановление - Включить + Активировать Текущее окно: @@ -199,13 +199,13 @@ Главная - Увеличение переднего окна после задержки + Масштабирование переднего окна после задержки - Отложенное увеличение + Отложенное масштабирование - Увеличить после {}с + Масштабировать после {}с Отмена @@ -229,13 +229,13 @@ Сохранить - Действительны горячие клавиши начинающиеся с Windows, Ctrl, Alt или Shift. + Действительны горячие клавиши начинающиеся с клавиши Windows, Ctrl, Alt или Shift. О программе - По умолчанию + Профиль по умолчанию Главная @@ -247,7 +247,7 @@ Выберите окно - Копия из + Копировать из Создать @@ -265,10 +265,10 @@ Профили - Настройки увеличения + Настройки масштабирования - Настройки увеличения + Настройки масштабирования Расширенные @@ -283,46 +283,46 @@ Windows (по умолчанию) - Переносной режим + Портативный режим Открыть расположение файла настроек - Автозагрузка + Запускать при включении системы - Magpie продолжит работать в фоновом режиме после закрытия главного окна + Magpie продолжит работать в фоне после закрытия главного окна - Отображение приложения в области уведомлений + Отображение приложения на панели задач Тема - Тёмный + Тёмная Windows (по умолчанию) - Светлый + Светлая Горячие клавиши - Внутриигровое наложение + Внутриигровой оверлей - Клавиша внутриигрового наложения + Клавиша внутриигрового оверлея - Увеличить + Масштабировать - Клавиша увеличения + Клавиша масштабирования Запуск @@ -334,28 +334,28 @@ Автоматически применяется, когда выходное изображение слишком велико, чтобы уместиться на экране - Эффект уменьшения по умолчанию + Эффект уменьшения масштаба по умолчанию - Экспорт + Экспортировать - Импорт + Импортировать - Импорт ScaleModels.json + Импортировать ScaleModels.json Больше настроек - Режимы увеличения + Режимы масштабирования - Для использования этой настройки нужно запустить от администратора + Для использования этой настройки нужно запустить приложение от имени администратора - Всегда запускаться от администратора + Всегда запускать приложение от имени администратора Периодически проверять наличие обновлений @@ -364,10 +364,10 @@ Скачать и установить - Примечания к выпуску + Информация о версии - Напомнить мне позже + Напомнить позже {} доступно @@ -376,7 +376,7 @@ Другие ссылки - Руководство по сотрудничеству + Руководство по содействию ЧаВо @@ -385,7 +385,7 @@ Лицензия - Github хранилище + Github репозиторий Отлично @@ -406,13 +406,13 @@ Его используют следующие профили: - Вы уверены, что хотите удалить этот режим увеличения? + Вы уверены, что хотите удалить этот режим масштабирования? - Перетаскивание не поддерживается при работе от администратора + Перетаскивание не поддерживается при работе от имени администратора - Перетащите чтобы переупорядочить + Перетащите, чтобы переупорядочить Опустить @@ -421,19 +421,19 @@ Поднять - Новый режим увеличения + Новый режим масштабирования - Новый режим увеличения + Новый режим масштабирования - Увеличение + Масштабирование - Копия из + Копировать из - Нет + Ничего Создать @@ -442,19 +442,19 @@ Название - Высота (множитель увеличения) + Высота (множитель масштабирования) Высота (пиксели) - Ширина (множитель увеличения) + Ширина (множитель масштабирования) - Заполняет экран, изображение может растягиваться + Заполняет экран, изображение может быть растянуто - Подогнать + Вписывание Ширина (пиксели) @@ -466,19 +466,19 @@ Абсолютно - Установить размер после увеличения + Установить размер после масштабирования Множитель - Выставить множитель увеличения относительно входного изображения + Выставить множитель масштабирования относительно входного изображения Все мониторы - Выставить множитель увеличения после заполнения экрана пропорциональным увеличением + Выставить множитель масштабирования после заполнения экрана пропорциональным масштабированием Общие @@ -487,7 +487,7 @@ Режим 3D игры - Автоувеличение при переднем плане + Автоматическое масштабирование когда на переднем плане Способ захвата @@ -496,16 +496,16 @@ Предпочтительные мониторы - Монитор, ближайший к исходному окну + Ближайший монитор к исходному окну Разрешить дополнительную задержку для повышения производительности - Мониторы, пересекаемые исходным окном + Пересекаемые исходным окном мониторы - Режим увеличения + Режим масштабирования Запуск @@ -547,19 +547,19 @@ Переупорядочить - Сбой разбора + Сбой парсинга - Нет + Ничего Производительность - Графическая карта + Видеокарта - Показать счётчик кадров в секунду + Отображать счётчик FPS Вертикальная синхронизация @@ -580,7 +580,7 @@ Версия - Проверять предварительные обновления + Проверить наличие обновлений предварительного просмотра Автоматически проверять наличие обновлений @@ -592,7 +592,7 @@ Не удалось проверить наличие обновлений, повторите попытку позже - Проверяем обновления + Проверяем наличие обновлений Отмена @@ -601,16 +601,16 @@ Скачать и установить - Примечания к выпуску + Информация о версии - Попробуйте ещё раз + Повторить попытку - {} доступен + {} доступно - Magpie уже самая свежая + Magpie уже актуально Скачивание не удалось @@ -622,10 +622,10 @@ Отключить DirectFlip - Рисовать указатель + Отображать курсор - Подогнать скорость указателя при увеличении + Подогнать скорость курсора при масштабировании Алгоритм интерполяции @@ -637,7 +637,7 @@ Ближайший сосед - Не увеличивать + Не масштабировать Как в исходном окне @@ -649,49 +649,49 @@ Исходное окно - Ограничено Graphics Capture и Desktop Duplication + Ограничено захватом графики и дупликации рабочего стола - Захват заголовка + Заголовок захвата - Обрезать вручную + Пользовательская обрезка - Низ + Снизу - Лево + Слева - пкс + пкс. - Право + Справа - Верх + Сверху - Выключить изменение размера окна при увеличении + Выключить изменение размера окна при масштабировании - Даёт небольшой прирост производительности. Однако эффекты должны перекомпилироваться при каждом изменении их параметров + Даёт небольшой прирост производительности. Однако эффекты должны быть перекомпилированы при каждом изменении их параметров Сделать параметры эффекта встроенными - Уведомления и всплывающие окна некоторых приложений будут блокироваться + Уведомления и всплывающие окна некоторых приложений будут заблокированы - Симуляция эксклюзивного полного экрана при увеличении + Симуляция эксклюзивного полного экрана при масштабировании - Для использования этой настройки, включите "Отображать приложение в области уведомления" + Для использования этой настройки, включите "Отображать приложение в панели задач" - Сворачивание в область уведомления при запуске + Сворачивать на панель задач при запуске Ошибка @@ -700,25 +700,25 @@ Предупреждение - Локальный файл настроек имеет неизвестную версию и может быть неправильно разобран. + Локальный файл настроек имеет неизвестную версию и может быть анализирован неправильно. Продолжить - Выход + Выйти - Глобальный файл настроек имеет неизвестную версию и может быть разобран неправильно. + Глобальный файл настроек имеет неизвестную версию и может быть анализирован неправильно. Продолжить - Включить переносной режим + Включить портативный режим - Эти настройки только для разработки + Эти настройки предназначены только для разработчиков Настройки разработчика @@ -730,13 +730,13 @@ Отключить кэш эффектов - Сохранение исходного кода при разборе эффектов + Сохранение исходного кода при анализе эффектов Рассматривать предупреждения как ошибки при компиляции эффектов - Выход + Выйти Расположение файла настроек: @@ -746,25 +746,25 @@ Файл настроек не является правильным JSON - Не удалось разобрать файл настроек + Не удалось анализировать файл настроек - Выкл + Выкл. - Вкл + Вкл. - Экспорт режимов увеличения + Экспорт режимов масштабирования - Импорт режимов увеличения + Импорт режимов масштабирования - Импорт ScaleModels.json + Импортировать ScaleModels.json - Некоторые эффекты нельзя разобрать + Некоторые эффекты нельзя анализировать Неизвестный эффект @@ -776,13 +776,13 @@ Обновить настройки - Правка + Изменить Параметры запуска - Полупрозрачность + Непрозрачность Профилировщик @@ -800,13 +800,13 @@ Статистика кадра - Переключить к кадровой частоте + Переключиться на кадровую частоту - Переключить к времени кадра + Переключиться на тайминги кадра - Затраты времени + Тайминги Итого @@ -815,16 +815,16 @@ Разблокировать - Переключить к эффектам + Переключиться на эффекты - Переключить к проходам + Переключиться на проходы Выключить кэш шрифтов - Разрешить увеличение развёрнутых или полноэкранных окон + Разрешить масштабирование развёрнутых или полноэкранных окон JSON файл @@ -839,9 +839,12 @@ Выберите исполняемый файл для запуска программы - Отслеживание производительности отрисовки при увеличении + Отслеживать производительность рендеринга при масштабировании - Увеличение переднего окна или останов увеличения + Масштабирование переднего окна или остановка масштабирования + + + Зафиксировать \ No newline at end of file From 7b3acec04756df826e61b7192323be7d8c35aa0b Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Tue, 7 Nov 2023 23:57:22 +0800 Subject: [PATCH 45/70] =?UTF-8?q?feat:=20=E9=80=82=E9=85=8D=20Win11=2023H2?= =?UTF-8?q?=20(#747)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie/app.manifest | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Magpie/app.manifest b/src/Magpie/app.manifest index d58a747ec..6c18ff4ff 100644 --- a/src/Magpie/app.manifest +++ b/src/Magpie/app.manifest @@ -23,6 +23,7 @@ + From 9aa39af2a18e54bb1a8077628d93f0c7640c7388 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Thu, 9 Nov 2023 19:20:47 +0800 Subject: [PATCH 46/70] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E8=B4=B4?= =?UTF-8?q?=E9=9D=A0=E5=B8=83=E5=B1=80=E5=BC=B9=E7=AA=97=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=20(#749)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Magpie/MainWindow.cpp | 33 ++++++++++++++++++++++++++++++++- src/Magpie/MainWindow.h | 1 + 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Magpie/MainWindow.cpp b/src/Magpie/MainWindow.cpp index 9a26b1fa7..381fd0d7c 100644 --- a/src/Magpie/MainWindow.cpp +++ b/src/Magpie/MainWindow.cpp @@ -123,6 +123,20 @@ bool MainWindow::Create(HINSTANCE hInstance, const RECT& windowRect, bool isMaxi ); SetLayeredWindowAttributes(_hwndTitleBar, 0, 255, LWA_ALPHA); + if (Win32Utils::GetOSVersion().IsWin11()) { + // 如果鼠标正位于一个按钮上,贴靠布局弹窗会出现在按钮下方。我们利用这个特性来修正贴靠布局弹窗的位置 + _hwndMaximizeButton = CreateWindow( + L"BUTTON", + L"", + WS_VISIBLE | WS_CHILD | WS_DISABLED | BS_OWNERDRAW, + 0, 0, 0, 0, + _hwndTitleBar, + NULL, + hInstance, + NULL + ); + } + _content.TitleBar().SizeChanged([this](winrt::IInspectable const&, winrt::SizeChangedEventArgs const&) { _ResizeTitleBarWindow(); }); @@ -233,6 +247,11 @@ LRESULT MainWindow::_TitleBarWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM LRESULT MainWindow::_TitleBarMessageHandler(UINT msg, WPARAM wParam, LPARAM lParam) noexcept { switch (msg) { + case WM_CTLCOLORBTN: + { + // 使原生按钮控件透明,虽然整个标题栏窗口都是不可见的 + return NULL; + } case WM_NCHITTEST: { POINT cursorPos{ GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam) }; @@ -427,16 +446,28 @@ void MainWindow::_ResizeTitleBarWindow() noexcept { const float dpiScale = _currentDpi / float(USER_DEFAULT_SCREEN_DPI); // 将标题栏窗口置于 XAML Islands 窗口上方 + const int titleBarWidth = (int)std::ceilf(rect.Width * dpiScale); SetWindowPos( _hwndTitleBar, HWND_TOP, (int)std::floorf(rect.X * dpiScale), (int)std::floorf(rect.Y * dpiScale) + _GetTopBorderHeight(), - (int)std::ceilf(rect.Width * dpiScale), + titleBarWidth, (int)std::floorf(rect.Height * dpiScale + 1), // 不知为何,直接向上取整有时无法遮盖 TitleBarControl SWP_SHOWWINDOW ); + if (_hwndMaximizeButton) { + static const float captionButtonHeightInDips = [&]() { + return titleBar.CaptionButtons().CaptionButtonSize().Height; + }(); + + const int captionButtonHeightInPixels = (int)std::ceilf(captionButtonHeightInDips * dpiScale); + + // 确保原生按钮和标题栏按钮高度相同 + MoveWindow(_hwndMaximizeButton, 0, 0, titleBarWidth, captionButtonHeightInPixels, FALSE); + } + // 设置标题栏窗口的最大化样式,这样才能展示正确的文字提示 LONG_PTR style = GetWindowLongPtr(_hwndTitleBar, GWL_STYLE); SetWindowLongPtr(_hwndTitleBar, GWL_STYLE, diff --git a/src/Magpie/MainWindow.h b/src/Magpie/MainWindow.h index 54dd10eba..7972ac8b2 100644 --- a/src/Magpie/MainWindow.h +++ b/src/Magpie/MainWindow.h @@ -24,6 +24,7 @@ class MainWindow : public XamlWindowT void _ResizeTitleBarWindow() noexcept; HWND _hwndTitleBar = NULL; + HWND _hwndMaximizeButton = NULL; bool _trackingMouse = false; }; From f66f192dcc525ad45c35413291b5bd293f6f383a Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:50:43 +0800 Subject: [PATCH 47/70] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E7=89=88=20WinUI=20(#750)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 支持正式版 WinUI * chore: 修复 Reg-free WinRT * chore: 删除一个不再需要的魔法 --- Magpie.sln | 3 ++ publish.py | 21 ++++-------- src/Common.Post.props | 2 +- src/HybridCRT.props | 2 +- src/Magpie.App/Magpie.App.vcxproj | 15 +++++---- src/Magpie.App/ProfilePage.xaml | 6 ---- src/Magpie.App/packages.config | 4 +-- src/Magpie/Magpie.vcxproj | 13 +++---- src/Magpie/packages.config | 4 +-- src/WinUI.props | 26 ++++++++++++++ src/extract_winui_runtime.py | 56 +++++++++++++++++++++++++++++++ src/fix_resfiles.py | 15 +++++++++ 12 files changed, 127 insertions(+), 40 deletions(-) create mode 100644 src/WinUI.props create mode 100644 src/extract_winui_runtime.py create mode 100644 src/fix_resfiles.py diff --git a/Magpie.sln b/Magpie.sln index c2966d90e..816f238ce 100644 --- a/Magpie.sln +++ b/Magpie.sln @@ -23,7 +23,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Directory.Build.props = Directory.Build.props src\Common.Pre.props = src\Common.Pre.props src\Common.Post.props = src\Common.Post.props + src\extract_winui_runtime.py = src\extract_winui_runtime.py + src\fix_resfiles.py = src\fix_resfiles.py HybridCRT.props = HybridCRT.props + src\WinUI.props = src\WinUI.props EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shared", "src\Shared\Shared.vcxitems", "{4EB33017-68C1-40FE-877A-BCFAB2832F18}" diff --git a/publish.py b/publish.py index d1043d083..fd5af9838 100644 --- a/publish.py +++ b/publish.py @@ -131,16 +131,9 @@ def remove_file(file): pass -# 删除文件夹,忽略错误 -def remove_folder(folder): - try: - shutil.rmtree(folder) - except: - pass - - -remove_file("Microsoft.Web.WebView2.Core.dll") - +for folder in ["Microsoft.UI.Xaml", "Magpie.App"]: + shutil.rmtree(folder, ignore_errors=True) + for pattern in ["*.pdb", "*.lib", "*.exp", "*.winmd", "*.xml", "*.xbf", "dummy.*"]: for file in glob.glob(pattern): remove_file(file) @@ -149,8 +142,7 @@ def remove_folder(folder): if file != "resources.pri": remove_file(file) -for folder in ["Microsoft.UI.Xaml", "Magpie.App"]: - remove_folder(folder) +remove_file("Microsoft.Web.WebView2.Core.dll") print("清理完毕", flush=True) @@ -162,9 +154,7 @@ def remove_folder(folder): ##################################################################### # 取最新的 Windows SDK -windowsSdkDir = sorted( - glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*") -)[-1] +windowsSdkDir = max(glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*")) makepriPath = windowsSdkDir + "\\x64\\makepri.exe" if not os.access(makepriPath, os.X_OK): raise Exception("未找到 makepri") @@ -186,6 +176,7 @@ def remove_folder(folder): continue # 我们仅需 19h1 和 21h1 的资源,分别用于 Win10 和 Win11 + # 小写 compact 仅存在于预发行版 WinUI 的资源中 for key in ["compact", "Compact", "v1", "rs2", "rs3", "rs4", "rs5"]: if key in name: # 将文件内容替换为一个空格(Base64 为 "IA==") diff --git a/src/Common.Post.props b/src/Common.Post.props index 4f2ad80d4..aa5ae3350 100644 --- a/src/Common.Post.props +++ b/src/Common.Post.props @@ -5,7 +5,7 @@ true true low - $(SolutionDir)\obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ + $(SolutionDir)obj\$(Platform)\$(Configuration)\$(MSBuildProjectName)\ $(IntDir)Generated Files\ diff --git a/src/HybridCRT.props b/src/HybridCRT.props index 1549406a2..703e75893 100644 --- a/src/HybridCRT.props +++ b/src/HybridCRT.props @@ -2,7 +2,7 @@ - + diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index e211c5f2b..c90f77248 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -1,7 +1,7 @@ - + + - true true @@ -45,6 +45,7 @@ + @@ -554,18 +555,18 @@ - - + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + \ No newline at end of file diff --git a/src/Magpie.App/ProfilePage.xaml b/src/Magpie.App/ProfilePage.xaml index 37d1ba4da..65fff5c6c 100644 --- a/src/Magpie.App/ProfilePage.xaml +++ b/src/Magpie.App/ProfilePage.xaml @@ -272,12 +272,6 @@ Style="{StaticResource ExpanderContentSettingStyle}"> - - - - diff --git a/src/Magpie.App/packages.config b/src/Magpie.App/packages.config index 5ca7a4dad..0a6627990 100644 --- a/src/Magpie.App/packages.config +++ b/src/Magpie.App/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/src/Magpie/Magpie.vcxproj b/src/Magpie/Magpie.vcxproj index 6cd6e9917..19bb8c351 100644 --- a/src/Magpie/Magpie.vcxproj +++ b/src/Magpie/Magpie.vcxproj @@ -1,7 +1,7 @@ + - 16.0 Win32Proj @@ -29,6 +29,7 @@ + @@ -83,18 +84,18 @@ - - + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - + + + \ No newline at end of file diff --git a/src/Magpie/packages.config b/src/Magpie/packages.config index 5ca7a4dad..0a6627990 100644 --- a/src/Magpie/packages.config +++ b/src/Magpie/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/src/WinUI.props b/src/WinUI.props new file mode 100644 index 000000000..d801de33e --- /dev/null +++ b/src/WinUI.props @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + false + Microsoft.UI.Xaml.dll + + + + + + + + + diff --git a/src/extract_winui_runtime.py b/src/extract_winui_runtime.py new file mode 100644 index 000000000..5970d57c4 --- /dev/null +++ b/src/extract_winui_runtime.py @@ -0,0 +1,56 @@ +import sys +import os +import glob +import zipfile +import shutil + +if len(sys.argv) != 2: + raise Exception("请勿直接运行此脚本") + +platform = sys.argv[1] +if not platform in ["x64", "ARM64"]: + raise Exception("非法参数") + +os.chdir(os.path.dirname(__file__) + "\\..\\packages") +packagesFolder = os.getcwd() + +winuiPkg = max(glob.glob("Microsoft.UI.Xaml*")) + +intDir = f"..\\obj\\{platform}\\WinUI" + +if "prerelease" in winuiPkg: + # 预览版本的 WinUI 无需解压 + shutil.rmtree(intDir, ignore_errors=True) +else: + os.makedirs(intDir, exist_ok=True) + os.chdir(intDir) + + needExtract = True + + try: + with open("version.txt") as f: + if f.read() == winuiPkg: + needExtract = False + except: + pass + + if needExtract: + with zipfile.ZipFile( + # 取最新的包 + max( + glob.glob( + f"{packagesFolder}\\{winuiPkg}\\tools\\AppX\\{platform}\\Release\\Microsoft.UI.Xaml*.appx" + ) + ) + ) as appx: + # 收集要解压的文件 + members = ["Microsoft.UI.Xaml.dll", "resources.pri"] + # 编译需要 Assets 文件夹,编译完成后会删除它 + for file in appx.namelist(): + if file.startswith("Microsoft.UI.Xaml/Assets"): + members.append(file) + + appx.extractall(members=members) + + with open("version.txt", mode="w") as f: + f.write(winuiPkg) diff --git a/src/fix_resfiles.py b/src/fix_resfiles.py new file mode 100644 index 000000000..0cc0ae5d2 --- /dev/null +++ b/src/fix_resfiles.py @@ -0,0 +1,15 @@ +import sys +import os + +if len(sys.argv) != 2: + raise Exception("请勿直接运行此脚本") + +with open(sys.argv[1], "r+") as f: + lines = [] + for line in f.readlines(): + if not "\\packages\\Microsoft.UI.Xaml" in line or "prerelease" in line: + lines.append(line) + + f.seek(os.SEEK_SET) + f.truncate() + f.writelines(lines) From b10a3a3f220cde85fa8308ed1676d1a4125d41d0 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:53:32 +0800 Subject: [PATCH 48/70] =?UTF-8?q?chore:=20=E6=9B=B4=E6=96=B0=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/Compilation guide.md | 4 ++-- "docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/Compilation guide.md b/docs/Compilation guide.md index 218ef347a..640a580a1 100644 --- a/docs/Compilation guide.md +++ b/docs/Compilation guide.md @@ -6,8 +6,8 @@ In order to compile Magpie, you need to first install: 2. [CMake](https://cmake.org/) You can also use the built-in CMake of Visual Studio, which is located at `%ProgramFiles%\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin`. -3. [Python](https://www.python.org/) 3.6+ -4. [Conan](https://conan.io/) v1 +3. [Python](https://www.python.org/) 3.11+ +4. [Conan](https://conan.io/) ```bash pip install conan diff --git "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" index 55e5e0724..b65467c54 100644 --- "a/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" +++ "b/docs/\347\274\226\350\257\221\346\214\207\345\215\227.md" @@ -6,8 +6,8 @@ 2. [CMake](https://cmake.org/) 你也可以使用 Visual Studio 内置的 CMake,它位于 `%ProgramFiles%\Microsoft Visual Studio\2022\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin`。 -3. [Python](https://www.python.org/) 3.6+ -4. [Conan](https://conan.io/) v1 +3. [Python](https://www.python.org/) 3.11+ +4. [Conan](https://conan.io/) ```bash pip install conan From 7978f4b06d1fe6f2a6296194beb3c796a9102625 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:12:55 +0800 Subject: [PATCH 49/70] Create dependabot.yml --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..7a2e76cd2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" From 5c60eac06aba7ad318887bed2eb580248fc48fa6 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:17:53 +0800 Subject: [PATCH 50/70] Update dependabot.yml --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7a2e76cd2..c3a444b34 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: "/" schedule: interval: "weekly" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From b8a6452b674846f435e385f84f5fbdf82371fbed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:21:38 +0800 Subject: [PATCH 51/70] chore(deps): bump actions/checkout from 3 to 4 (#752) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/wiki.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5062ca13c..479d2087d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 469ec916e..03169280e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: diff --git a/.github/workflows/wiki.yml b/.github/workflows/wiki.yml index b9846e18a..8e5ddcf73 100644 --- a/.github/workflows/wiki.yml +++ b/.github/workflows/wiki.yml @@ -10,7 +10,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: From db7e24a4ca4220d3b4fa8fe178cd7c9f083bdd82 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:36:53 +0800 Subject: [PATCH 52/70] Update dependabot.yml --- .github/dependabot.yml | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c3a444b34..f28125d2d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,12 +5,27 @@ version: 2 updates: - - package-ecosystem: "nuget" + - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: "nuget" + directory: "/src/Magpie.App" + schedule: + interval: "weekly" + + - package-ecosystem: "nuget" + directory: "/src/Magpie.Core" + schedule: + interval: "weekly" + + - package-ecosystem: "nuget" + directory: "/src/Magpie" + schedule: + interval: "weekly" + + - package-ecosystem: "nuget" + directory: "/tools/MPVHookTextureParser" schedule: interval: "weekly" From a80cc8ee8b57576ae5e986b0aabf45a2b7d173d4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:38:03 +0800 Subject: [PATCH 53/70] chore(deps): bump directxtex_desktop_win10 (#753) Bumps [directxtex_desktop_win10](https://github.com/microsoft/DirectXTex) from 2023.9.6.1 to 2023.10.31.1. - [Release notes](https://github.com/microsoft/DirectXTex/releases) - [Changelog](https://github.com/microsoft/DirectXTex/blob/main/HISTORY.md) - [Commits](https://github.com/microsoft/DirectXTex/commits) --- updated-dependencies: - dependency-name: directxtex_desktop_win10 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/MPVHookTextureParser/packages.config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/MPVHookTextureParser/packages.config b/tools/MPVHookTextureParser/packages.config index ed8a951ff..95b17a349 100644 --- a/tools/MPVHookTextureParser/packages.config +++ b/tools/MPVHookTextureParser/packages.config @@ -1,5 +1,5 @@ - + - + \ No newline at end of file From a412739a0f544355ef3d22b188bf11b198340cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Mon, 13 Nov 2023 11:56:21 +0800 Subject: [PATCH 54/70] =?UTF-8?q?chore:=20Dependabot=20=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20C++?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/dependabot.yml | 20 ------------------- .../MPVHookTextureParser.vcxproj | 4 ++-- tools/MPVHookTextureParser/packages.config | 2 +- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f28125d2d..92c44a82b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,23 +9,3 @@ updates: directory: "/" schedule: interval: "weekly" - - - package-ecosystem: "nuget" - directory: "/src/Magpie.App" - schedule: - interval: "weekly" - - - package-ecosystem: "nuget" - directory: "/src/Magpie.Core" - schedule: - interval: "weekly" - - - package-ecosystem: "nuget" - directory: "/src/Magpie" - schedule: - interval: "weekly" - - - package-ecosystem: "nuget" - directory: "/tools/MPVHookTextureParser" - schedule: - interval: "weekly" diff --git a/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj b/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj index 6e2d5540a..b072f564a 100644 --- a/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj +++ b/tools/MPVHookTextureParser/MPVHookTextureParser.vcxproj @@ -81,14 +81,14 @@ - + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - + \ No newline at end of file diff --git a/tools/MPVHookTextureParser/packages.config b/tools/MPVHookTextureParser/packages.config index 95b17a349..6c5d457ef 100644 --- a/tools/MPVHookTextureParser/packages.config +++ b/tools/MPVHookTextureParser/packages.config @@ -1,4 +1,4 @@ - + From d9ca118dc5f27234de61edaba0e7734c91c08a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Mon, 13 Nov 2023 12:00:26 +0800 Subject: [PATCH 55/70] =?UTF-8?q?chore:=20=E4=BC=98=E5=8C=96=20Updater=20?= =?UTF-8?q?=E6=B8=85=E5=8D=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Updater/app.manifest | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Updater/app.manifest b/src/Updater/app.manifest index cea549eaf..ad8fd85ef 100644 --- a/src/Updater/app.manifest +++ b/src/Updater/app.manifest @@ -2,14 +2,16 @@ - + PerMonitorV2 + + SegmentHeap - + Date: Mon, 13 Nov 2023 12:32:22 +0800 Subject: [PATCH 56/70] =?UTF-8?q?chore:=20Release=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=8B=E5=AE=9A=E4=B9=89=20WINRT=5FNO=5FSOURCE=5FLOCATION=20?= =?UTF-8?q?=E4=BB=A5=E5=87=8F=E5=B0=8F=E5=8C=85=E7=9A=84=E4=BD=93=E7=A7=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common.Post.props | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Common.Post.props b/src/Common.Post.props index aa5ae3350..7a9ed7b6d 100644 --- a/src/Common.Post.props +++ b/src/Common.Post.props @@ -49,7 +49,10 @@ true true true - NDEBUG;%(PreprocessorDefinitions) + + + + NDEBUG;WINRT_NO_SOURCE_LOCATION;%(PreprocessorDefinitions) UseLinkTimeCodeGeneration From 9b3a5e283cf5aeadb9b221a08d5a3b22fe2c874b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=97=AD?= Date: Mon, 13 Nov 2023 12:38:55 +0800 Subject: [PATCH 57/70] =?UTF-8?q?chore:=20=E4=BD=BF=E7=94=A8=2064=20?= =?UTF-8?q?=E4=BD=8D=E7=BC=96=E8=AF=91=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Directory.Build.props b/Directory.Build.props index ee002f86b..6f73dc610 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,8 @@ + + x64 + stdcpp20 From bdca371a6f897090ab6a8b01f57bb17d0e11e630 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Wed, 15 Nov 2023 19:17:36 +0800 Subject: [PATCH 58/70] =?UTF-8?q?=E6=8F=90=E9=AB=98=E5=BC=80=E5=8F=91?= =?UTF-8?q?=E8=80=85=E9=80=89=E9=A1=B9=E7=9A=84=E9=97=A8=E6=A7=9B=20(#744)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 添加设置项管理开发者选项是否显示 * feat: 双击版本号显示开发者选项 * feat: 启用开发者模式时显示提示 * UI: 优化提示样式 * feat: 实现 MainPage::ShowToast * chore: 优化注释 * UI: 优化 Toast 样式 --- src/Magpie.App/AboutPage.cpp | 9 +++ src/Magpie.App/AboutPage.h | 2 + src/Magpie.App/AboutPage.xaml | 3 +- src/Magpie.App/AboutViewModel.cpp | 8 ++ src/Magpie.App/AboutViewModel.h | 3 + src/Magpie.App/AboutViewModel.idl | 2 + src/Magpie.App/AppSettings.cpp | 17 ++++ src/Magpie.App/AppSettings.h | 7 ++ src/Magpie.App/MainPage.cpp | 58 +++++++++++++- src/Magpie.App/MainPage.h | 2 + src/Magpie.App/MainPage.idl | 2 + src/Magpie.App/MainPage.xaml | 7 ++ src/Magpie.App/Resources.language-en-US.resw | 3 + .../Resources.language-zh-Hans.resw | 5 +- src/Magpie.App/SettingsPage.xaml | 78 ++++++++++--------- src/Magpie.App/SettingsViewModel.cpp | 15 ++++ src/Magpie.App/SettingsViewModel.h | 3 + src/Magpie.App/SettingsViewModel.idl | 2 + 18 files changed, 187 insertions(+), 39 deletions(-) diff --git a/src/Magpie.App/AboutPage.cpp b/src/Magpie.App/AboutPage.cpp index a370a1abd..835b1e501 100644 --- a/src/Magpie.App/AboutPage.cpp +++ b/src/Magpie.App/AboutPage.cpp @@ -7,6 +7,15 @@ namespace winrt::Magpie::App::implementation { +void AboutPage::VersionTextBlock_DoubleTapped(IInspectable const&, Input::DoubleTappedRoutedEventArgs const&) { + if (!_viewModel.IsDeveloperMode() && (GetAsyncKeyState(VK_MENU) & 0x8000)) { + _viewModel.IsDeveloperMode(true); + + hstring message = ResourceLoader::GetForCurrentView().GetString(L"About_DeveloperModeEnabled"); + Application::Current().as().MainPage().ShowToast(message); + } +} + void AboutPage::BugReportButton_Click(IInspectable const&, RoutedEventArgs const&) { Win32Utils::ShellOpen(L"https://github.com/Blinue/Magpie/issues/new?assignees=&labels=bug&template=01_bug.yaml"); } diff --git a/src/Magpie.App/AboutPage.h b/src/Magpie.App/AboutPage.h index 8f3e3635a..93358e8c6 100644 --- a/src/Magpie.App/AboutPage.h +++ b/src/Magpie.App/AboutPage.h @@ -8,6 +8,8 @@ struct AboutPage : AboutPageT { return _viewModel; } + void VersionTextBlock_DoubleTapped(IInspectable const&, Input::DoubleTappedRoutedEventArgs const&); + void BugReportButton_Click(IInspectable const&, RoutedEventArgs const&); void FeatureRequestButton_Click(IInspectable const&, RoutedEventArgs const&); void DiscussionsButton_Click(IInspectable const&, RoutedEventArgs const&); diff --git a/src/Magpie.App/AboutPage.xaml b/src/Magpie.App/AboutPage.xaml index d830a40e7..226a44c9e 100644 --- a/src/Magpie.App/AboutPage.xaml +++ b/src/Magpie.App/AboutPage.xaml @@ -23,7 +23,8 @@ Spacing="4"> - diff --git a/src/Magpie.App/AboutViewModel.cpp b/src/Magpie.App/AboutViewModel.cpp index 59c8fe4d0..2b892ea0f 100644 --- a/src/Magpie.App/AboutViewModel.cpp +++ b/src/Magpie.App/AboutViewModel.cpp @@ -81,6 +81,14 @@ hstring AboutViewModel::Version() const noexcept { )); } +bool AboutViewModel::IsDeveloperMode() const noexcept { + return AppSettings::Get().IsDeveloperMode(); +} + +void AboutViewModel::IsDeveloperMode(bool value) { + AppSettings::Get().IsDeveloperMode(value); +} + fire_and_forget AboutViewModel::CheckForUpdates() { return UpdateService::Get().CheckForUpdatesAsync(false); } diff --git a/src/Magpie.App/AboutViewModel.h b/src/Magpie.App/AboutViewModel.h index 3e71efd6b..ab8a4fe1c 100644 --- a/src/Magpie.App/AboutViewModel.h +++ b/src/Magpie.App/AboutViewModel.h @@ -21,6 +21,9 @@ struct AboutViewModel : AboutViewModelT { hstring Version() const noexcept; + bool IsDeveloperMode() const noexcept; + void IsDeveloperMode(bool value); + fire_and_forget CheckForUpdates(); bool IsCheckForPreviewUpdates() const noexcept; diff --git a/src/Magpie.App/AboutViewModel.idl b/src/Magpie.App/AboutViewModel.idl index 322f8d0e4..cadd86678 100644 --- a/src/Magpie.App/AboutViewModel.idl +++ b/src/Magpie.App/AboutViewModel.idl @@ -6,6 +6,8 @@ namespace Magpie.App { String Version { get; }; + Boolean IsDeveloperMode; + void CheckForUpdates(); Boolean IsCheckingForUpdates { get; }; Boolean IsCheckForUpdatesButtonEnabled { get; }; diff --git a/src/Magpie.App/AppSettings.cpp b/src/Magpie.App/AppSettings.cpp index 9cf22ee09..5161c84af 100644 --- a/src/Magpie.App/AppSettings.cpp +++ b/src/Magpie.App/AppSettings.cpp @@ -397,6 +397,20 @@ void AppSettings::CountdownSeconds(uint32_t value) noexcept { SaveAsync(); } +void AppSettings::IsDeveloperMode(bool value) noexcept { + _isDeveloperMode = value; + if (!value) { + // 关闭开发者模式则禁用所有开发者选项 + _isDebugMode = false; + _isDisableEffectCache = false; + _isDisableFontCache = false; + _isSaveEffectSources = false; + _isWarningsAreErrors = false; + } + + SaveAsync(); +} + void AppSettings::IsAlwaysRunAsAdmin(bool value) noexcept { if (_isAlwaysRunAsAdmin == value) { return; @@ -494,6 +508,8 @@ bool AppSettings::_Save(const _AppSettingsData& data) noexcept { writer.Bool(data._isAutoRestore); writer.Key("countdownSeconds"); writer.Uint(data._countdownSeconds); + writer.Key("developerMode"); + writer.Bool(data._isDeveloperMode); writer.Key("debugMode"); writer.Bool(data._isDebugMode); writer.Key("disableEffectCache"); @@ -640,6 +656,7 @@ void AppSettings::_LoadSettings(const rapidjson::GenericObject 5) { _countdownSeconds = 3; } + JsonHelper::ReadBool(root, "developerMode", _isDeveloperMode); JsonHelper::ReadBool(root, "debugMode", _isDebugMode); JsonHelper::ReadBool(root, "disableEffectCache", _isDisableEffectCache); JsonHelper::ReadBool(root, "disableFontCache", _isDisableFontCache); diff --git a/src/Magpie.App/AppSettings.h b/src/Magpie.App/AppSettings.h index a3816b93e..9582d0532 100644 --- a/src/Magpie.App/AppSettings.h +++ b/src/Magpie.App/AppSettings.h @@ -48,6 +48,7 @@ struct _AppSettingsData { bool _isPortableMode = false; bool _isAlwaysRunAsAdmin = false; + bool _isDeveloperMode = false; bool _isDebugMode = false; bool _isDisableEffectCache = false; bool _isDisableFontCache = false; @@ -185,6 +186,12 @@ class AppSettings : private _AppSettingsData { _countdownSecondsChangedEvent.remove(token); } + bool IsDeveloperMode() const noexcept { + return _isDeveloperMode; + } + + void IsDeveloperMode(bool value) noexcept; + bool IsDebugMode() const noexcept { return _isDebugMode; } diff --git a/src/Magpie.App/MainPage.cpp b/src/Magpie.App/MainPage.cpp index 760650edc..c15392a02 100644 --- a/src/Magpie.App/MainPage.cpp +++ b/src/Magpie.App/MainPage.cpp @@ -169,7 +169,7 @@ void MainPage::NavigationView_DisplayModeChanged(MUXC::NavigationView const& nv, nv.IsPaneOpen(true); } - // HACK! + // !!! HACK !!! // 使导航栏的可滚动区域不会覆盖标题栏 FrameworkElement menuItemsScrollViewer = nv.GetTemplateChild(L"MenuItemsScrollViewer").as(); menuItemsScrollViewer.Margin({ 0,isExpanded ? TitleBar().ActualHeight() : 0.0,0,0}); @@ -210,6 +210,62 @@ void MainPage::NavigateToAboutPage() { nv.SelectedItem(nv.FooterMenuItems().GetAt(0)); } +fire_and_forget MainPage::ShowToast(const hstring& message) { + // !!! HACK !!! + // 重用 TeachingTip 有一个 bug:前一个 Toast 正在消失时新的 Toast 不会显示。为了 + // 规避它,我们每次都创建新的 TeachingTip,但要保留旧对象的引用,因为播放动画时销毁 + // 会导致崩溃。oldToastTeachingTip 的生存期可确保动画播放完毕。 + MUXC::TeachingTip oldToastTeachingTip = ToastTeachingTip(); + if (oldToastTeachingTip) { + UnloadObject(oldToastTeachingTip); + } + + weak_ref weakTeachingTip; + { + // 创建新的 TeachingTip + MUXC::TeachingTip newTeachingTip = FindName(L"ToastTeachingTip").as(); + ToastTextBlock().Text(message); + newTeachingTip.IsOpen(true); + + // !!! HACK !!! + // 我们不想要 IsLightDismissEnabled,因为它会阻止用户和其他控件交互,但我们也不想要关闭按钮,于是 + // 手动隐藏它。我们必须在模板加载完成后再做这些,但 TeachingTip 没有 Opening 事件,于是有了又一个 + // workaround:监听 ToastTextBlock 的 LayoutUpdated 事件,它在 TeachingTip 显示前必然会被引发。 + ToastTextBlock().LayoutUpdated([weak(weak_ref(newTeachingTip))](IInspectable const&, IInspectable const&) { + auto toastTeachingTip = weak.get(); + if (!toastTeachingTip) { + return; + } + + // 隐藏关闭按钮 + if (DependencyObject closeButton = toastTeachingTip.GetTemplateChild(L"AlternateCloseButton")) { + closeButton.as().Visibility(Visibility::Collapsed); + } + + // 减小 Flyout 尺寸 + if (DependencyObject container = toastTeachingTip.GetTemplateChild(L"TailOcclusionGrid")) { + container.as().MinWidth(0.0); + } + }); + + weakTeachingTip = newTeachingTip; + } + + auto weakThis = get_weak(); + CoreDispatcher dispatcher = Dispatcher(); + // 显示时长固定 2 秒 + co_await 2s; + co_await dispatcher; + + if (weakThis.get()) { + MUXC::TeachingTip curTeachingTip = ToastTeachingTip(); + if (curTeachingTip == weakTeachingTip.get()) { + // 如果已经显示新的 Toast 则无需关闭,因为 newTeachingTip 已被卸载(但仍在生存期内) + curTeachingTip.IsOpen(false); + } + } +} + static Color Win32ColorToWinRTColor(COLORREF color) { return { 255, GetRValue(color), GetGValue(color), GetBValue(color) }; } diff --git a/src/Magpie.App/MainPage.h b/src/Magpie.App/MainPage.h index cc3c3ee53..8d53ddc6f 100644 --- a/src/Magpie.App/MainPage.h +++ b/src/Magpie.App/MainPage.h @@ -38,6 +38,8 @@ struct MainPage : MainPageT { void NavigateToAboutPage(); + fire_and_forget ShowToast(const hstring& message); + private: void _UpdateTheme(bool updateIcons = true); diff --git a/src/Magpie.App/MainPage.idl b/src/Magpie.App/MainPage.idl index a252bc721..b7d2602dc 100644 --- a/src/Magpie.App/MainPage.idl +++ b/src/Magpie.App/MainPage.idl @@ -8,5 +8,7 @@ namespace Magpie.App { NewProfileViewModel NewProfileViewModel { get; }; void NavigateToAboutPage(); + + void ShowToast(String message); } } diff --git a/src/Magpie.App/MainPage.xaml b/src/Magpie.App/MainPage.xaml index 1dd3d8a71..bdc17a769 100644 --- a/src/Magpie.App/MainPage.xaml +++ b/src/Magpie.App/MainPage.xaml @@ -8,8 +8,15 @@ Loaded="Loaded" mc:Ignorable="d"> + + + + + + Commit + + Developer mode is enabled. + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-zh-Hans.resw b/src/Magpie.App/Resources.language-zh-Hans.resw index acd65f303..1b53b28b6 100644 --- a/src/Magpie.App/Resources.language-zh-Hans.resw +++ b/src/Magpie.App/Resources.language-zh-Hans.resw @@ -59,7 +59,7 @@ : using a System.ComponentModel.TypeConverter : and then encoded with base64 encoding. --> - + @@ -847,4 +847,7 @@ 提交 + + 开发者模式已启用。 + \ No newline at end of file diff --git a/src/Magpie.App/SettingsPage.xaml b/src/Magpie.App/SettingsPage.xaml index 4022a443a..8a7eb79fe 100644 --- a/src/Magpie.App/SettingsPage.xaml +++ b/src/Magpie.App/SettingsPage.xaml @@ -141,43 +141,49 @@ IsOn="{x:Bind ViewModel.IsInlineParams, Mode=TwoWay}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Magpie.App/SettingsViewModel.cpp b/src/Magpie.App/SettingsViewModel.cpp index 50b6de7f5..f753a270a 100644 --- a/src/Magpie.App/SettingsViewModel.cpp +++ b/src/Magpie.App/SettingsViewModel.cpp @@ -212,6 +212,21 @@ void SettingsViewModel::IsInlineParams(bool value) noexcept { _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsInlineParams")); } +bool SettingsViewModel::IsDeveloperMode() const noexcept { + return AppSettings::Get().IsDeveloperMode(); +} + +void SettingsViewModel::IsDeveloperMode(bool value) noexcept { + AppSettings& settings = AppSettings::Get(); + + if (settings.IsDeveloperMode() == value) { + return; + } + + settings.IsDeveloperMode(value); + _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsDeveloperMode")); +} + bool SettingsViewModel::IsDebugMode() const noexcept { return AppSettings::Get().IsDebugMode(); } diff --git a/src/Magpie.App/SettingsViewModel.h b/src/Magpie.App/SettingsViewModel.h index a50601138..eb65a398e 100644 --- a/src/Magpie.App/SettingsViewModel.h +++ b/src/Magpie.App/SettingsViewModel.h @@ -53,6 +53,9 @@ struct SettingsViewModel : SettingsViewModelT { bool IsInlineParams() const noexcept; void IsInlineParams(bool value) noexcept; + bool IsDeveloperMode() const noexcept; + void IsDeveloperMode(bool value) noexcept; + bool IsDebugMode() const noexcept; void IsDebugMode(bool value) noexcept; diff --git a/src/Magpie.App/SettingsViewModel.idl b/src/Magpie.App/SettingsViewModel.idl index 58ad3b1fa..2c8b8f7f9 100644 --- a/src/Magpie.App/SettingsViewModel.idl +++ b/src/Magpie.App/SettingsViewModel.idl @@ -21,6 +21,8 @@ namespace Magpie.App { Boolean IsAllowScalingMaximized; Boolean IsSimulateExclusiveFullscreen; Boolean IsInlineParams; + + Boolean IsDeveloperMode; Boolean IsDebugMode; Boolean IsDisableEffectCache; Boolean IsDisableFontCache; From 4bb371bf86547b971d836260953e6776dd298568 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 18 Nov 2023 12:12:33 +0100 Subject: [PATCH 59/70] Translations update from Hosted Weblate (#758) * Translated using Weblate (Chinese (Traditional)) Currently translated at 93.0% (227 of 244 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/zh_Hant/ * Translated using Weblate (Japanese) Currently translated at 100.0% (244 of 244 strings) Translation: Magpie/UI Translate-URL: https://hosted.weblate.org/projects/magpie/ui/ja/ --------- Co-authored-by: Frost_Koi Co-authored-by: animeojisan --- src/Magpie.App/Resources.language-ja.resw | 3 +++ src/Magpie.App/Resources.language-zh-Hant.resw | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/Magpie.App/Resources.language-ja.resw b/src/Magpie.App/Resources.language-ja.resw index 948266941..1cbb86c78 100644 --- a/src/Magpie.App/Resources.language-ja.resw +++ b/src/Magpie.App/Resources.language-ja.resw @@ -847,4 +847,7 @@ コミット + + デベロッパーモードが有効。 + \ No newline at end of file diff --git a/src/Magpie.App/Resources.language-zh-Hant.resw b/src/Magpie.App/Resources.language-zh-Hant.resw index 0ea3f9468..f80a1950b 100644 --- a/src/Magpie.App/Resources.language-zh-Hant.resw +++ b/src/Magpie.App/Resources.language-zh-Hant.resw @@ -787,4 +787,16 @@ 垂直同步 + + 透明度 + + + 鎖定 + + + 停用字型快取 + + + 解除鎖定 + \ No newline at end of file From d233fc95aeeba3588b2fb45dedc24f55c6907f98 Mon Sep 17 00:00:00 2001 From: Xu <34770031+Blinue@users.noreply.github.com> Date: Mon, 20 Nov 2023 21:17:30 +0800 Subject: [PATCH 60/70] =?UTF-8?q?=E6=83=B0=E6=80=A7=E5=8A=A0=E8=BD=BD?= =?UTF-8?q?=E6=9F=90=E4=BA=9B=E6=8E=A7=E4=BB=B6=E4=BB=A5=E6=8F=90=E9=AB=98?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8A=A0=E8=BD=BD=E9=80=9F=E5=BA=A6=20(#754)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * perf: 惰性加载开发者选项 * chore: MainPage 重命名为 RootPage * perf: 惰性加载检查更新 UI * perf: 更多惰性加载 * perf: 更多惰性加载 * chore: 优化格式 --- src/Magpie.App/AboutPage.cpp | 3 +- src/Magpie.App/AboutPage.idl | 3 + src/Magpie.App/AboutPage.xaml | 14 ++-- src/Magpie.App/AboutViewModel.cpp | 8 ++- src/Magpie.App/AboutViewModel.h | 2 + src/Magpie.App/AboutViewModel.idl | 2 + src/Magpie.App/App.cpp | 10 +-- src/Magpie.App/App.h | 10 +-- src/Magpie.App/App.idl | 4 +- src/Magpie.App/EffectParametersViewModel.h | 6 +- src/Magpie.App/EffectParametersViewModel.idl | 5 +- src/Magpie.App/HomePage.idl | 3 + src/Magpie.App/HomePage.xaml | 7 +- src/Magpie.App/HomeViewModel.cpp | 2 +- src/Magpie.App/Magpie.App.vcxproj | 14 ++-- src/Magpie.App/Magpie.App.vcxproj.filters | 2 +- src/Magpie.App/PageFrame.cpp | 2 +- src/Magpie.App/ProfilePage.idl | 4 ++ src/Magpie.App/ProfilePage.xaml | 20 +++--- src/Magpie.App/ProfileViewModel.cpp | 16 ++--- src/Magpie.App/ProfileViewModel.h | 4 +- src/Magpie.App/{MainPage.cpp => RootPage.cpp} | 62 +++++++++--------- src/Magpie.App/{MainPage.h => RootPage.h} | 10 +-- src/Magpie.App/{MainPage.idl => RootPage.idl} | 4 +- .../{MainPage.xaml => RootPage.xaml} | 2 +- src/Magpie.App/ScalingConfigurationPage.idl | 3 + src/Magpie.App/ScalingConfigurationPage.xaml | 14 ++-- src/Magpie.App/ScalingModeItem.cpp | 2 +- src/Magpie.App/SettingsPage.idl | 3 + src/Magpie.App/SettingsPage.xaml | 16 +++-- src/Magpie.App/TitlebarControl.cpp | 2 +- src/Magpie.App/WrapPanel.cpp | 64 +++++++++---------- src/Magpie/MainWindow.cpp | 2 +- src/Magpie/MainWindow.h | 2 +- src/Magpie/XamlApp.cpp | 4 +- src/Magpie/XamlWindow.h | 2 +- src/Magpie/app.manifest | 2 +- 37 files changed, 186 insertions(+), 149 deletions(-) rename src/Magpie.App/{MainPage.cpp => RootPage.cpp} (88%) rename src/Magpie.App/{MainPage.h => RootPage.h} (94%) rename src/Magpie.App/{MainPage.idl => RootPage.idl} (78%) rename src/Magpie.App/{MainPage.xaml => RootPage.xaml} (99%) diff --git a/src/Magpie.App/AboutPage.cpp b/src/Magpie.App/AboutPage.cpp index 835b1e501..e4bbee1c2 100644 --- a/src/Magpie.App/AboutPage.cpp +++ b/src/Magpie.App/AboutPage.cpp @@ -8,11 +8,12 @@ namespace winrt::Magpie::App::implementation { void AboutPage::VersionTextBlock_DoubleTapped(IInspectable const&, Input::DoubleTappedRoutedEventArgs const&) { + // 按住 Alt 键双击版本号即可启用开发者模式 if (!_viewModel.IsDeveloperMode() && (GetAsyncKeyState(VK_MENU) & 0x8000)) { _viewModel.IsDeveloperMode(true); hstring message = ResourceLoader::GetForCurrentView().GetString(L"About_DeveloperModeEnabled"); - Application::Current().as().MainPage().ShowToast(message); + Application::Current().as().RootPage().ShowToast(message); } } diff --git a/src/Magpie.App/AboutPage.idl b/src/Magpie.App/AboutPage.idl index f72fcab22..c40c0a4a3 100644 --- a/src/Magpie.App/AboutPage.idl +++ b/src/Magpie.App/AboutPage.idl @@ -3,5 +3,8 @@ namespace Magpie.App { AboutPage(); AboutViewModel ViewModel { get; }; + + // https://github.com/microsoft/microsoft-ui-xaml/issues/7579 + void UnloadObject(Windows.UI.Xaml.DependencyObject object); } } diff --git a/src/Magpie.App/AboutPage.xaml b/src/Magpie.App/AboutPage.xaml index 226a44c9e..b0d00cf1f 100644 --- a/src/Magpie.App/AboutPage.xaml +++ b/src/Magpie.App/AboutPage.xaml @@ -37,22 +37,24 @@ - + IsActive="True" /> + VerticalAlignment="Center" /> - UpdateStatus::Checking; +} + bool AboutViewModel::IsCheckingForUpdates() const noexcept { return UpdateService::Get().Status() == UpdateStatus::Checking; } bool AboutViewModel::IsErrorWhileChecking() const noexcept { - UpdateService& service = UpdateService::Get(); - return service.Status() == UpdateStatus::ErrorWhileChecking; + return UpdateService::Get().Status() == UpdateStatus::ErrorWhileChecking; } void AboutViewModel::IsErrorWhileChecking(bool value) noexcept { @@ -257,6 +260,7 @@ void AboutViewModel::Retry() { void AboutViewModel::_UpdateService_StatusChanged(UpdateStatus status) { _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsCheckingForUpdates")); _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsCheckForUpdatesButtonEnabled")); + _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsAnyUpdateStatus")); _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsErrorWhileChecking")); _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsNoUpdate")); _propertyChangedEvent(*this, PropertyChangedEventArgs(L"IsAvailable")); diff --git a/src/Magpie.App/AboutViewModel.h b/src/Magpie.App/AboutViewModel.h index ab8a4fe1c..f050510d3 100644 --- a/src/Magpie.App/AboutViewModel.h +++ b/src/Magpie.App/AboutViewModel.h @@ -34,6 +34,8 @@ struct AboutViewModel : AboutViewModelT { bool IsAutoCheckForUpdates() const noexcept; void IsAutoCheckForUpdates(bool value) noexcept; + bool IsAnyUpdateStatus() const noexcept; + bool IsCheckingForUpdates() const noexcept; bool IsErrorWhileChecking() const noexcept; diff --git a/src/Magpie.App/AboutViewModel.idl b/src/Magpie.App/AboutViewModel.idl index cadd86678..e4369e51e 100644 --- a/src/Magpie.App/AboutViewModel.idl +++ b/src/Magpie.App/AboutViewModel.idl @@ -15,6 +15,8 @@ namespace Magpie.App { Boolean IsAutoCheckForUpdates; Boolean IsCheckForPreviewUpdates; + Boolean IsAnyUpdateStatus { get; }; + Boolean IsErrorWhileChecking; Boolean IsNoUpdate; Boolean IsAvailable { get; }; diff --git a/src/Magpie.App/App.cpp b/src/Magpie.App/App.cpp index ed8ecd901..b0a4a1a1f 100644 --- a/src/Magpie.App/App.cpp +++ b/src/Magpie.App/App.cpp @@ -130,14 +130,14 @@ void App::HwndMain(uint64_t value) noexcept { _hwndMainChangedEvent(*this, value); } -void App::MainPage(Magpie::App::MainPage const& mainPage) noexcept { +void App::RootPage(Magpie::App::RootPage const& rootPage) noexcept { // 显示主窗口前等待 EffectsService 完成初始化 EffectsService::Get().WaitForInitialize(); - if (mainPage) { - // 不存储对 MainPage 的强引用 - // XAML Islands 内部保留着对 MainPage 的强引用,MainPage 的生命周期是无法预知的 - _mainPage = weak_ref(mainPage); + if (rootPage) { + // 不存储对 RootPage 的强引用 + // XAML Islands 内部保留着对 RootPage 的强引用,RootPage 的生命周期是无法预知的 + _rootPage = weak_ref(rootPage); } else { UpdateService::Get().ClosingMainWindow(); } diff --git a/src/Magpie.App/App.h b/src/Magpie.App/App.h index c214b37fd..24e91fe1f 100644 --- a/src/Magpie.App/App.h +++ b/src/Magpie.App/App.h @@ -39,12 +39,12 @@ class App : public AppT2 { } // 在由外部源引发的回调中可能返回 nullptr - // 这是因为用户关闭主窗口后 MainPage 不会立刻析构 - Magpie::App::MainPage MainPage() const noexcept { - return _mainPage.get(); + // 这是因为用户关闭主窗口后 RootPage 不会立刻析构 + Magpie::App::RootPage RootPage() const noexcept { + return _rootPage.get(); } - void MainPage(Magpie::App::MainPage const& mainPage) noexcept; + void RootPage(Magpie::App::RootPage const& rootPage) noexcept; void Quit() const noexcept; @@ -56,7 +56,7 @@ class App : public AppT2 { HWND _hwndMain{}; event> _hwndMainChangedEvent; - weak_ref _mainPage{ nullptr }; + weak_ref _rootPage{ nullptr }; event> _hostWndFocusChangedEvent; bool _isHostWndFocused = false; diff --git a/src/Magpie.App/App.idl b/src/Magpie.App/App.idl index 0fc83cb99..d08f97cd4 100644 --- a/src/Magpie.App/App.idl +++ b/src/Magpie.App/App.idl @@ -20,7 +20,7 @@ #include "CandidateWindowItem.idl" #include "NewProfileViewModel.idl" #include "AboutViewModel.idl" -#include "MainPage.idl" +#include "RootPage.idl" #include "AboutPage.idl" #include "HomePage.idl" #include "ScalingConfigurationPage.idl" @@ -63,7 +63,7 @@ namespace Magpie.App { UInt64 HwndMain; event Windows.Foundation.EventHandler HwndMainChanged; - MainPage MainPage; + RootPage RootPage; void Quit(); void Restart(); diff --git a/src/Magpie.App/EffectParametersViewModel.h b/src/Magpie.App/EffectParametersViewModel.h index 7f5a6aec0..4bfcff531 100644 --- a/src/Magpie.App/EffectParametersViewModel.h +++ b/src/Magpie.App/EffectParametersViewModel.h @@ -12,7 +12,7 @@ namespace winrt::Magpie::App::implementation { struct ScalingModeBoolParameter : ScalingModeBoolParameterT { ScalingModeBoolParameter(uint32_t index, const hstring& label, bool initValue) - : _index(index), _label(label), _value(initValue) { + : _index(index), _label(box_value(label)), _value(initValue) { } event_token PropertyChanged(PropertyChangedEventHandler const& handler) { @@ -36,7 +36,7 @@ struct ScalingModeBoolParameter : ScalingModeBoolParameterT _propertyChangedEvent; const uint32_t _index; - const hstring _label; + IInspectable _label; bool _value; }; diff --git a/src/Magpie.App/EffectParametersViewModel.idl b/src/Magpie.App/EffectParametersViewModel.idl index 4cb463e9e..c4c4db697 100644 --- a/src/Magpie.App/EffectParametersViewModel.idl +++ b/src/Magpie.App/EffectParametersViewModel.idl @@ -3,7 +3,8 @@ namespace Magpie.App { ScalingModeBoolParameter(UInt32 index, String label, Boolean initValue); Boolean Value; - String Label { get; }; + // Bind to CheckBox.Content + Object Label { get; }; } runtimeclass ScalingModeFloatParameter : Windows.UI.Xaml.Data.INotifyPropertyChanged { @@ -14,7 +15,7 @@ namespace Magpie.App { String ValueText { get; }; Double Minimum { get; }; Double Maximum { get; }; - Double Step{ get; }; + Double Step { get; }; } runtimeclass EffectParametersViewModel { diff --git a/src/Magpie.App/HomePage.idl b/src/Magpie.App/HomePage.idl index 8b6a7ac51..82275a504 100644 --- a/src/Magpie.App/HomePage.idl +++ b/src/Magpie.App/HomePage.idl @@ -3,5 +3,8 @@ namespace Magpie.App { HomePage(); HomeViewModel ViewModel { get; }; + + // https://github.com/microsoft/microsoft-ui-xaml/issues/7579 + void UnloadObject(Windows.UI.Xaml.DependencyObject object); } } diff --git a/src/Magpie.App/HomePage.xaml b/src/Magpie.App/HomePage.xaml index 960a1389d..474356992 100644 --- a/src/Magpie.App/HomePage.xaml +++ b/src/Magpie.App/HomePage.xaml @@ -10,11 +10,12 @@ - + Severity="Informational"> ().MainPage().NavigateToAboutPage(); + Application::Current().as().RootPage().NavigateToAboutPage(); } void HomeViewModel::ReleaseNotes() { diff --git a/src/Magpie.App/Magpie.App.vcxproj b/src/Magpie.App/Magpie.App.vcxproj index c90f77248..07fe30521 100644 --- a/src/Magpie.App/Magpie.App.vcxproj +++ b/src/Magpie.App/Magpie.App.vcxproj @@ -166,8 +166,8 @@ HomePage.xaml Code - - MainPage.xaml + + RootPage.xaml Code @@ -318,8 +318,8 @@ HomePage.xaml Code - - MainPage.xaml + + RootPage.xaml Code @@ -462,8 +462,8 @@ HomePage.xaml Code - - MainPage.xaml + + RootPage.xaml Code @@ -496,7 +496,7 @@ Designer - + Designer diff --git a/src/Magpie.App/Magpie.App.vcxproj.filters b/src/Magpie.App/Magpie.App.vcxproj.filters index 08554d9ca..4371d15aa 100644 --- a/src/Magpie.App/Magpie.App.vcxproj.filters +++ b/src/Magpie.App/Magpie.App.vcxproj.filters @@ -211,7 +211,7 @@ - + Pages diff --git a/src/Magpie.App/PageFrame.cpp b/src/Magpie.App/PageFrame.cpp index 3845e152c..5c3bfaaac 100644 --- a/src/Magpie.App/PageFrame.cpp +++ b/src/Magpie.App/PageFrame.cpp @@ -47,7 +47,7 @@ void PageFrame::Loading(FrameworkElement const&, IInspectable const&) { void PageFrame::Loaded(IInspectable const&, RoutedEventArgs const&) { // Win10 中更新 ToolTip 的主题 - XamlUtils::UpdateThemeOfTooltips(*this, Application::Current().as().MainPage().ActualTheme()); + XamlUtils::UpdateThemeOfTooltips(*this, Application::Current().as().RootPage().ActualTheme()); } void PageFrame::ScrollViewer_PointerPressed(IInspectable const&, PointerRoutedEventArgs const&) { diff --git a/src/Magpie.App/ProfilePage.idl b/src/Magpie.App/ProfilePage.idl index cb52311d5..d72eaea9e 100644 --- a/src/Magpie.App/ProfilePage.idl +++ b/src/Magpie.App/ProfilePage.idl @@ -3,6 +3,10 @@ namespace Magpie.App { ProfilePage(); ProfileViewModel ViewModel { get; }; + static Windows.Globalization.NumberFormatting.INumberFormatter2 NumberFormatter { get; }; + + // https://github.com/microsoft/microsoft-ui-xaml/issues/7579 + void UnloadObject(Windows.UI.Xaml.DependencyObject object); } } diff --git a/src/Magpie.App/ProfilePage.xaml b/src/Magpie.App/ProfilePage.xaml index 65fff5c6c..ca0415fdb 100644 --- a/src/Magpie.App/ProfilePage.xaml +++ b/src/Magpie.App/ProfilePage.xaml @@ -189,9 +189,10 @@ - + x:Load="{x:Bind ViewModel.IsNotDefaultProfile, Mode=OneTime}"> @@ -209,9 +210,10 @@ IsOn="{x:Bind ViewModel.Is3DGameMode, Mode=TwoWay}" /> - + x:Load="{x:Bind ViewModel.HasMultipleMonitors, Mode=OneTime}"> @@ -229,9 +231,10 @@ - + x:Load="{x:Bind ViewModel.IsShowGraphicsCardSettingsCard, Mode=OneTime}"> @@ -476,9 +479,10 @@ - + x:Load="{x:Bind ViewModel.IsNotDefaultProfile, Mode=OneTime}"> diff --git a/src/Magpie.App/ProfileViewModel.cpp b/src/Magpie.App/ProfileViewModel.cpp index 0d0da8ec6..47ddf8ec5 100644 --- a/src/Magpie.App/ProfileViewModel.cpp +++ b/src/Magpie.App/ProfileViewModel.cpp @@ -65,8 +65,8 @@ ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileId _icon = FontIcon(); App app = Application::Current().as(); - MainPage mainPage = app.MainPage(); - _themeChangedRevoker = mainPage.ActualThemeChanged( + RootPage rootPage = app.RootPage(); + _themeChangedRevoker = rootPage.ActualThemeChanged( auto_revoke, [this](FrameworkElement const& sender, IInspectable const&) { _LoadIcon(sender); @@ -77,8 +77,8 @@ ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileId _dpiChangedRevoker = _displayInformation.DpiChanged( auto_revoke, [this](DisplayInformation const&, IInspectable const&) { - if (MainPage mainPage = Application::Current().as().MainPage()) { - _LoadIcon(mainPage); + if (RootPage rootPage = Application::Current().as().RootPage()) { + _LoadIcon(rootPage); } } ); @@ -90,7 +90,7 @@ ProfileViewModel::ProfileViewModel(int profileIdx) : _isDefaultProfile(profileId _isProgramExist = Win32Utils::FileExists(_data->pathRule.c_str()); } - _LoadIcon(mainPage); + _LoadIcon(rootPage); } ResourceLoader resourceLoader = ResourceLoader::GetForCurrentView(); @@ -814,17 +814,17 @@ void ProfileViewModel::IsDisableDirectFlip(bool value) { AppSettings::Get().SaveAsync(); } -fire_and_forget ProfileViewModel::_LoadIcon(FrameworkElement const& mainPage) { +fire_and_forget ProfileViewModel::_LoadIcon(FrameworkElement const& rootPage) { std::wstring iconPath; SoftwareBitmap iconBitmap{ nullptr }; if (_isProgramExist) { auto weakThis = get_weak(); - const bool preferLightTheme = mainPage.ActualTheme() == ElementTheme::Light; + const bool preferLightTheme = rootPage.ActualTheme() == ElementTheme::Light; const bool isPackaged = _data->isPackaged; const std::wstring path = _data->pathRule; - CoreDispatcher dispatcher = mainPage.Dispatcher(); + CoreDispatcher dispatcher = rootPage.Dispatcher(); const uint32_t dpi = (uint32_t)std::lroundf(_displayInformation.LogicalDpi()); co_await resume_background(); diff --git a/src/Magpie.App/ProfileViewModel.h b/src/Magpie.App/ProfileViewModel.h index 501a8fe93..90a2745c1 100644 --- a/src/Magpie.App/ProfileViewModel.h +++ b/src/Magpie.App/ProfileViewModel.h @@ -154,7 +154,7 @@ struct ProfileViewModel : ProfileViewModelT { void IsDisableDirectFlip(bool value); private: - fire_and_forget _LoadIcon(FrameworkElement const& mainPage); + fire_and_forget _LoadIcon(FrameworkElement const& rootPage); bool _isProgramExist = true; @@ -171,7 +171,7 @@ struct ProfileViewModel : ProfileViewModelT { // 可以保存此指针的原因是:用户停留在此页面时不会有缩放配置被创建或删除 Profile* _data = nullptr; - MainPage::ActualThemeChanged_revoker _themeChangedRevoker; + RootPage::ActualThemeChanged_revoker _themeChangedRevoker; Windows::Graphics::Display::DisplayInformation _displayInformation{ nullptr }; Windows::Graphics::Display::DisplayInformation::DpiChanged_revoker _dpiChangedRevoker; diff --git a/src/Magpie.App/MainPage.cpp b/src/Magpie.App/RootPage.cpp similarity index 88% rename from src/Magpie.App/MainPage.cpp rename to src/Magpie.App/RootPage.cpp index c15392a02..fa1b58a4c 100644 --- a/src/Magpie.App/MainPage.cpp +++ b/src/Magpie.App/RootPage.cpp @@ -1,7 +1,7 @@ #include "pch.h" -#include "MainPage.h" -#if __has_include("MainPage.g.cpp") -#include "MainPage.g.cpp" +#include "RootPage.h" +#if __has_include("RootPage.g.cpp") +#include "RootPage.g.cpp" #endif #include "XamlUtils.h" @@ -31,10 +31,10 @@ namespace winrt::Magpie::App::implementation { static constexpr const uint32_t FIRST_PROFILE_ITEM_IDX = 4; -MainPage::MainPage() { +RootPage::RootPage() { _themeChangedRevoker = AppSettings::Get().ThemeChanged(auto_revoke, [this](Theme) { _UpdateTheme(); }); _colorValuesChangedRevoker = _uiSettings.ColorValuesChanged( - auto_revoke, { this, &MainPage::_UISettings_ColorValuesChanged }); + auto_revoke, { this, &RootPage::_UISettings_ColorValuesChanged }); _displayInformation = DisplayInformation::GetForCurrentView(); _dpiChangedRevoker = _displayInformation.DpiChanged( @@ -42,19 +42,19 @@ MainPage::MainPage() { ProfileService& profileService = ProfileService::Get(); _profileAddedRevoker = profileService.ProfileAdded( - auto_revoke, { this, &MainPage::_ProfileService_ProfileAdded }); + auto_revoke, { this, &RootPage::_ProfileService_ProfileAdded }); _profileRenamedRevoker = profileService.ProfileRenamed( - auto_revoke, { this, &MainPage::_ProfileService_ProfileRenamed }); + auto_revoke, { this, &RootPage::_ProfileService_ProfileRenamed }); _profileRemovedRevoker = profileService.ProfileRemoved( - auto_revoke, { this, &MainPage::_ProfileService_ProfileRemoved }); + auto_revoke, { this, &RootPage::_ProfileService_ProfileRemoved }); _profileMovedRevoker = profileService.ProfileMoved( - auto_revoke, { this, &MainPage::_ProfileService_ProfileReordered }); + auto_revoke, { this, &RootPage::_ProfileService_ProfileReordered }); // 设置 Language 属性帮助 XAML 选择合适的字体,比如繁体中文使用 Microsoft JhengHei UI,日语使用 Yu Gothic UI Language(LocalizationService::Get().Language()); } -MainPage::~MainPage() { +RootPage::~RootPage() { ContentDialogHelper::CloseActiveDialog(); // 不手动置空会内存泄露 @@ -65,8 +65,8 @@ MainPage::~MainPage() { AppXReader::ClearCache(); } -void MainPage::InitializeComponent() { - MainPageT::InitializeComponent(); +void RootPage::InitializeComponent() { + RootPageT::InitializeComponent(); _UpdateTheme(false); @@ -88,7 +88,7 @@ void MainPage::InitializeComponent() { } } -void MainPage::Loaded(IInspectable const&, RoutedEventArgs const&) { +void RootPage::Loaded(IInspectable const&, RoutedEventArgs const&) { // 消除焦点框 IsTabStop(true); Focus(FocusState::Programmatic); @@ -98,7 +98,7 @@ void MainPage::Loaded(IInspectable const&, RoutedEventArgs const&) { XamlUtils::UpdateThemeOfTooltips(*this, ActualTheme()); } -void MainPage::NavigationView_SelectionChanged( +void RootPage::NavigationView_SelectionChanged( MUXC::NavigationView const&, MUXC::NavigationViewSelectionChangedEventArgs const& args ) { @@ -139,7 +139,7 @@ void MainPage::NavigationView_SelectionChanged( } } -void MainPage::NavigationView_PaneOpening(MUXC::NavigationView const&, IInspectable const&) { +void RootPage::NavigationView_PaneOpening(MUXC::NavigationView const&, IInspectable const&) { if (Win32Utils::GetOSVersion().IsWin11()) { // Win11 中 Tooltip 自动适应主题 return; @@ -158,11 +158,11 @@ void MainPage::NavigationView_PaneOpening(MUXC::NavigationView const&, IInspecta } } -void MainPage::NavigationView_PaneClosing(MUXC::NavigationView const&, MUXC::NavigationViewPaneClosingEventArgs const&) { +void RootPage::NavigationView_PaneClosing(MUXC::NavigationView const&, MUXC::NavigationViewPaneClosingEventArgs const&) { XamlUtils::UpdateThemeOfTooltips(*this, ActualTheme()); } -void MainPage::NavigationView_DisplayModeChanged(MUXC::NavigationView const& nv, MUXC::NavigationViewDisplayModeChangedEventArgs const&) { +void RootPage::NavigationView_DisplayModeChanged(MUXC::NavigationView const& nv, MUXC::NavigationViewDisplayModeChangedEventArgs const&) { bool isExpanded = nv.DisplayMode() == MUXC::NavigationViewDisplayMode::Expanded; nv.IsPaneToggleButtonVisible(!isExpanded); if (isExpanded) { @@ -177,7 +177,7 @@ void MainPage::NavigationView_DisplayModeChanged(MUXC::NavigationView const& nv, XamlUtils::UpdateThemeOfTooltips(*this, ActualTheme()); } -fire_and_forget MainPage::NavigationView_ItemInvoked(MUXC::NavigationView const&, MUXC::NavigationViewItemInvokedEventArgs const& args) { +fire_and_forget RootPage::NavigationView_ItemInvoked(MUXC::NavigationView const&, MUXC::NavigationViewItemInvokedEventArgs const& args) { if (args.InvokedItemContainer() == NewProfileNavigationViewItem()) { const UINT dpi = (UINT)std::lroundf(_displayInformation.LogicalDpi()); const bool isLightTheme = ActualTheme() == ElementTheme::Light; @@ -190,27 +190,27 @@ fire_and_forget MainPage::NavigationView_ItemInvoked(MUXC::NavigationView const& } } -void MainPage::ComboBox_DropDownOpened(IInspectable const&, IInspectable const&) { +void RootPage::ComboBox_DropDownOpened(IInspectable const&, IInspectable const&) { XamlUtils::UpdateThemeOfXamlPopups(XamlRoot(), ActualTheme()); } -void MainPage::NewProfileConfirmButton_Click(IInspectable const&, RoutedEventArgs const&) { +void RootPage::NewProfileConfirmButton_Click(IInspectable const&, RoutedEventArgs const&) { _newProfileViewModel.Confirm(); NewProfileFlyout().Hide(); } -void MainPage::NewProfileNameTextBox_KeyDown(IInspectable const&, Input::KeyRoutedEventArgs const& args) { +void RootPage::NewProfileNameTextBox_KeyDown(IInspectable const&, Input::KeyRoutedEventArgs const& args) { if (args.Key() == VirtualKey::Enter && _newProfileViewModel.IsConfirmButtonEnabled()) { NewProfileConfirmButton_Click(nullptr, nullptr); } } -void MainPage::NavigateToAboutPage() { +void RootPage::NavigateToAboutPage() { MUXC::NavigationView nv = RootNavigationView(); nv.SelectedItem(nv.FooterMenuItems().GetAt(0)); } -fire_and_forget MainPage::ShowToast(const hstring& message) { +fire_and_forget RootPage::ShowToast(const hstring& message) { // !!! HACK !!! // 重用 TeachingTip 有一个 bug:前一个 Toast 正在消失时新的 Toast 不会显示。为了 // 规避它,我们每次都创建新的 TeachingTip,但要保留旧对象的引用,因为播放动画时销毁 @@ -275,7 +275,7 @@ static bool IsColorLight(const Color& clr) { return 5 * clr.G + 2 * clr.R + clr.B > 8 * 128; } -void MainPage::_UpdateTheme(bool updateIcons) { +void RootPage::_UpdateTheme(bool updateIcons) { Theme theme = AppSettings::Get().Theme(); bool isDarkTheme = FALSE; @@ -308,7 +308,7 @@ void MainPage::_UpdateTheme(bool updateIcons) { } } -fire_and_forget MainPage::_LoadIcon(MUXC::NavigationViewItem const& item, const Profile& profile) { +fire_and_forget RootPage::_LoadIcon(MUXC::NavigationViewItem const& item, const Profile& profile) { weak_ref weakRef(item); bool preferLightTheme = ActualTheme() == ElementTheme::Light; @@ -369,7 +369,7 @@ fire_and_forget MainPage::_LoadIcon(MUXC::NavigationViewItem const& item, const } } -fire_and_forget MainPage::_UISettings_ColorValuesChanged(Windows::UI::ViewManagement::UISettings const&, IInspectable const&) { +fire_and_forget RootPage::_UISettings_ColorValuesChanged(Windows::UI::ViewManagement::UISettings const&, IInspectable const&) { auto weakThis = get_weak(); co_await Dispatcher(); @@ -384,7 +384,7 @@ fire_and_forget MainPage::_UISettings_ColorValuesChanged(Windows::UI::ViewManage _UpdateIcons(true); } -void MainPage::_UpdateIcons(bool skipDesktop) { +void RootPage::_UpdateIcons(bool skipDesktop) { IVector navMenuItems = RootNavigationView().MenuItems(); const std::vector& profiles = AppSettings::Get().Profiles(); @@ -398,7 +398,7 @@ void MainPage::_UpdateIcons(bool skipDesktop) { } } -void MainPage::_ProfileService_ProfileAdded(Profile& profile) { +void RootPage::_ProfileService_ProfileAdded(Profile& profile) { MUXC::NavigationViewItem item; item.Content(box_value(profile.name)); // 用于占位 @@ -410,21 +410,21 @@ void MainPage::_ProfileService_ProfileAdded(Profile& profile) { RootNavigationView().SelectedItem(item); } -void MainPage::_ProfileService_ProfileRenamed(uint32_t idx) { +void RootPage::_ProfileService_ProfileRenamed(uint32_t idx) { RootNavigationView().MenuItems() .GetAt(FIRST_PROFILE_ITEM_IDX + idx) .as() .Content(box_value(AppSettings::Get().Profiles()[idx].name)); } -void MainPage::_ProfileService_ProfileRemoved(uint32_t idx) { +void RootPage::_ProfileService_ProfileRemoved(uint32_t idx) { MUXC::NavigationView nv = RootNavigationView(); IVector menuItems = nv.MenuItems(); nv.SelectedItem(menuItems.GetAt(FIRST_PROFILE_ITEM_IDX - 1)); menuItems.RemoveAt(FIRST_PROFILE_ITEM_IDX + idx); } -void MainPage::_ProfileService_ProfileReordered(uint32_t profileIdx, bool isMoveUp) { +void RootPage::_ProfileService_ProfileReordered(uint32_t profileIdx, bool isMoveUp) { IVector menuItems = RootNavigationView().MenuItems(); uint32_t curIdx = FIRST_PROFILE_ITEM_IDX + profileIdx; diff --git a/src/Magpie.App/MainPage.h b/src/Magpie.App/RootPage.h similarity index 94% rename from src/Magpie.App/MainPage.h rename to src/Magpie.App/RootPage.h index 8d53ddc6f..bc35fca3e 100644 --- a/src/Magpie.App/MainPage.h +++ b/src/Magpie.App/RootPage.h @@ -1,5 +1,5 @@ #pragma once -#include "MainPage.g.h" +#include "RootPage.g.h" #include "WinRTUtils.h" namespace winrt::Magpie::App { @@ -8,9 +8,9 @@ struct Profile; namespace winrt::Magpie::App::implementation { -struct MainPage : MainPageT { - MainPage(); - ~MainPage(); +struct RootPage : RootPageT { + RootPage(); + ~RootPage(); void InitializeComponent(); @@ -76,7 +76,7 @@ struct MainPage : MainPageT { namespace winrt::Magpie::App::factory_implementation { -struct MainPage : MainPageT { +struct RootPage : RootPageT { }; } diff --git a/src/Magpie.App/MainPage.idl b/src/Magpie.App/RootPage.idl similarity index 78% rename from src/Magpie.App/MainPage.idl rename to src/Magpie.App/RootPage.idl index b7d2602dc..767bb447d 100644 --- a/src/Magpie.App/MainPage.idl +++ b/src/Magpie.App/RootPage.idl @@ -1,6 +1,6 @@ namespace Magpie.App { - runtimeclass MainPage : Windows.UI.Xaml.Controls.Page { - MainPage(); + runtimeclass RootPage : Windows.UI.Xaml.Controls.Page { + RootPage(); Microsoft.UI.Xaml.Controls.NavigationView RootNavigationView { get; }; TitleBarControl TitleBar { get; }; diff --git a/src/Magpie.App/MainPage.xaml b/src/Magpie.App/RootPage.xaml similarity index 99% rename from src/Magpie.App/MainPage.xaml rename to src/Magpie.App/RootPage.xaml index bdc17a769..7ffcc2986 100644 --- a/src/Magpie.App/MainPage.xaml +++ b/src/Magpie.App/RootPage.xaml @@ -1,4 +1,4 @@ - - + SelectionMode="None"> @@ -35,11 +36,12 @@ - + SelectionMode="None"> diff --git a/src/Magpie.App/ScalingModeItem.cpp b/src/Magpie.App/ScalingModeItem.cpp index 5abef753d..f2cae4c20 100644 --- a/src/Magpie.App/ScalingModeItem.cpp +++ b/src/Magpie.App/ScalingModeItem.cpp @@ -276,7 +276,7 @@ void ScalingModeItem::RenameButton_Click() { return; } - XamlUtils::CloseXamlPopups(Application::Current().as().MainPage().XamlRoot()); + XamlUtils::CloseXamlPopups(Application::Current().as().RootPage().XamlRoot()); _Data().name = _trimedRenameText; _propertyChangedEvent(*this, PropertyChangedEventArgs(L"Name")); diff --git a/src/Magpie.App/SettingsPage.idl b/src/Magpie.App/SettingsPage.idl index d40aaa248..baeeea534 100644 --- a/src/Magpie.App/SettingsPage.idl +++ b/src/Magpie.App/SettingsPage.idl @@ -3,5 +3,8 @@ namespace Magpie.App { SettingsPage(); SettingsViewModel ViewModel { get; }; + + // https://github.com/microsoft/microsoft-ui-xaml/issues/7579 + void UnloadObject(Windows.UI.Xaml.DependencyObject object); } } diff --git a/src/Magpie.App/SettingsPage.xaml b/src/Magpie.App/SettingsPage.xaml index 8a7eb79fe..1911eabf3 100644 --- a/src/Magpie.App/SettingsPage.xaml +++ b/src/Magpie.App/SettingsPage.xaml @@ -24,12 +24,13 @@ Style="{StaticResource ComboBoxSettingStyle}" /> - + Severity="Warning">