2025年9月5日 星期五

大蛇完全版 猶豫是不是要購買



很喜歡這套漫畫, 但紙本價錢太貴, 也沒折扣, 所以就不想買, 實體書看起來做的很精緻, 但不想在漫畫花那麼多錢, 要是有平價的版本就好了。查了日文版本定價 (おろち(1) (ビッグコミックススペシャル)), 也是蠻貴的, 紙本: 1980¥; kindle: 759¥ (kindle 便宜很多), 所以想改買電子書,【電子書】大蛇完全版(01), 但一直被是不是能下載和折扣問題搞得很煩, 現在很多電子書開始不提供下載, 所以這陣子我幾乎不買電子書, 實在不想在那邊查到底能不能下載, 很煩, 因為有的販售頁面寫的不清不楚, 查閱實在麻煩。

「おろち」翻譯成中文是大蛇, 它在日本文化中通常指的是傳說中的八岐大蛇 (やまたのおろち, Yamata no Orochi), 遠呂智 (おろち, Orochi) 是八岐大蛇名字的另一種漢字寫法。不過我還是喜歡「靈蛇」的翻譯。

一般要能下載以及是實體書定價的一半我才會購買電子書, 否則不買的機率大些 (可能連實體書也不買), 長鴻出版社在kobo上停止下載書檔, 我就對能下載的電子書信任感降低, 就算寫可以下載, 也不在像以前是 100% 相信, 而且 kobo 並不像 google book 退電子書很乾脆, 還要聯絡客服才能知道能不能退已購買的電子書, 很煩。原本不用擔心在 kobo 上買的能不能下載, 現在也變成要自己確認。
電子書詳細資料
張忠謀自傳
天下文化出版社
發布日期: 2024年11月29日
版本說明:天下文化
書籍ID:9786263559646
語言:中文
下載選項: 不支援 Adobe DRM 檔案下載
像張忠謀自傳這本是不能下載的。

在忙著找這些資訊後, 我火了, 買個東西這麼麻煩, 已經耗掉我的購買耐心, 所以就不想買了。發這篇文章發洩不滿。
Kobo週年慶 (https://r10.to/h5HjT5) 輸入 9HBD 全站73折
單筆滿$999送樂天點數99點,滿$1899送樂天點數199點(實際消費金額包含使用樂天點數&商店積分支付的金額)
滿額再抽閱讀器等好禮,至2025/9/10止 (https://r10.to/hPNXde)
後來看到這個資訊, 20250903 就購入了, 我是先買一本, 確定可以下載, 才買其他集數, 販售資訊也可以看到下載選項。總共花費: 172+540=712
電子書詳細資料
大蛇完全版(01)
由 楳圖一雄
第 1 冊 - 大蛇完全版
尖端出版
發布日期: 2025年8月8日
版本說明:尖端出版
書籍ID:9786264342278
語言:中文
下載選項:EPUB 3 (Adobe DRM)
rakuten 和 pchome 的 kobo 書籍好像看不到「下載選項」的說明, 一般我都到 kobo.com 看。

沒有彩頁, 只有最前面有一張扉頁彩頁, 這種版本能算完全版嗎? 和單行本有什麼差異?

amazon 已經不提供下載書檔, 所以我完全不考慮買 amazon 電子書, 基本上也不會去看 amazon 網站的書。

【其他】日本AMAZON收不到手機認證簡訊的解決方式

不要用信箱登入改用手機號登入 (假設你的手機號是0900123456)要輸入+886900123456 然後下一步不要打密碼改點下面的"傳送OTP碼登入", 這樣比較簡單, 一般人不會有日文對話能力。

這就是一種風險, 服務沒收掉, 但你的帳號進不去, 買的電子書等於全沒了。

大蛇類似來自魔界那種奇異故事,「米色利」換成「遠呂智」。所以如果故事吸引你, 那就會很喜歡這部漫畫, 但沒看過之前, 怎麼知道自己喜不喜歡呢? 像我就不愛洗禮的故事, 但我已經買了, 就覺得有點虧。

第3集的「戰鬥」是我最不滿的一個故事, 沒有把結局寫出來, 等於我看了老半天內容, 但不知道結局, 這是我最討厭的結束方式, 我花錢買的就是作者的故事, 給了一個沒結局要我自己想的結局, 那我花錢是幹麻用的? 而且大蛇不像來自魔界, 他有好多頁可以把故事好好描述, 不會因為頁數不足要做一些取捨。

香港作家余過的故事就都是有完整結局, 所以我很喜歡他的小說, 也是類似這種奇幻故事。

ref:
『漫画分享』楳图一雄《大蛇》完全版台版漫画开箱分享

2025年9月1日 星期一

2025823 大罷免 X 公投

黨 = 尚黑
20250823 是大罷免和核3公投投票日, 有選舉, 我都會去投, 這是唯一一個可以表達對政黨好惡的活動。投票是對政黨支持最直接的反應, 比民調真實多了。政治人物只有看到票減少了才會害怕, 民調低對他們是沒有警惕作用的。

就算是公投這種不那麼直接的選舉, 也是可以表達自己對政黨的喜好, 尤其是這種這麼政治性的議題, 大多數人都不會是核能專家, 你的贊成/反對是真的尊重專業, 還是以自己的政治立場來表達意見, 只有自己知道。

在網路上查看醫學相關知識, 能取代醫生治病嗎? 如果你查的資料和醫生說的不同, 你要堅持網路查的資料是對的嗎? 愛莉莎莎「喝橄欖油排膽結石」這個例子想必令人省思。

網路時代取得資訊來的容易, 很容易令人就以為某某事情就是這樣, 真正專業的東西是沒有這麼容易理解的。

如果核能發電程式發生 thread deak lock 問題, 一般人能體會這是多嚴重的事情嗎?

專業的東西並不是查查網路資訊, 就可以這麼容易做出決定。更何況這個議題正反2方都有他們的道理, 做決定比較像是一種選擇, 那種比較適合並不是那麼容易決定。

《專業之死》讀後心得:從愛莉莎莎和蒼藍鴿事件學到什麼?

如果是像安樂死、多元成家這樣的議題, 就會比較是民意的表現, 而不是政治傾向的對立, 很可惜沒有順便提出安樂死議題公投。

成案了!反核提案「核廢料放公投同意票最高3縣市」 4天獲近8千人支持

大罷免也如同之前的預測, 並沒有罷免掉任何一位立委, 而且不同意票的票數都還蠻高的, 真的是國民黨這麼得人心嗎?



2025年8月31日 星期日

劍星 cns mod

在討論區看到 CNS - Custom Nanosuit System mod, 這個 mod 需要 ue4ss, 可以以新增的方式增加衣服, 而不需要用取代的方式, 可以和原本的衣服一起存在, 真希望其他 mod 開發者都可以支援這個模組。

其實不只服裝, 臉部、髮型、耳環、眼鏡, 以及武器都有支援。

因為功能強大, 所以安裝稍微複雜點。解開後, SB 目錄直接覆蓋 /home/deck/.local/share/Steam/steamapps/common/StellarBlade/SB/ (steam deck 路徑)

Copy the extracted `SB` folder and merge it with your games `SB` folder. (ie, copy it into the root StellarBlade folder)

另外支援 CNS 的 mod 有 2 種, 一種只提供 .json 檔案, 一種和原本的 mod 一樣, 安裝方式也一樣。

.json 要放在 /home/deck/.local/share/Steam/steamapps/common/StellarBladeDemo/SB/Content/Paks/~mods/CustomNanosuitSystem 。

CNS 頁面也有列出使用 CNS 的 mod, 可以方便查找有支援 CNS 的 mod。

Compatible Skin Mods:
  1. Ada Wong (By JPTHEHERO)
  2. Cute Bikini (By Acutecorn)
  3. Backless Bodysuit (By Acutecorn)
  4. Diving Protection Suit - No Jacket (By Vorpine2)
  5. Cyber Suits w/No Tail (By Vorpine2)
  6. Heart Swimsuit (By shades2jad3d)
  7. First Descendant Bunny (By lilredsled)
  8. First Descendant Ines (By lilredsled) 
  9. First Descendant Bunny Apex Predator (By lilredsled)
  10. YoRHafy Silver & Shadow Kunoichi (By kesshin7)
  11. YoRHafy Wasteland Adventurer/Explorer (By keeshin7)
  12. Prae-Infinity Outfit (By roybjensen)
  13. EVE Delta Dress (By ItsRokaya)
  14. EVE Winter Outfit (By ItsRokaya)
  15. EVE X-Cyberpunk (By ItsRokaya)
  16. EVE Pink Bodysuit (By ItsRokaya)
  17. Echidna (By nyz333)
  18. Eve x Ines Summer Paradise (By IceAutumnBreath)
  19. EVE VIPGuard Outfit (By Reverse7R)
  20. Cyber Bunny No Stockings (By nomamad)
  21. [NSFW] Ms Claus Bikini (By Acutecorn)
  22. [NSFW] EVE Urban Xedge (By ItsRokaya)
  23. [NSFW] Akali (By AHaungo)
  24. [NSFW] Linyueru (By AHaungo)
  25. [NSFW] Tongquintao (By AHuengo)
  26. [NSFW] Lollipop Cheerleader (By AzureiWolf)
  27. [NSFW] Secretary Outfit (By roybjensen)
  28. [NSFW] White Shibari (By shades2jad3d)
  29. [NSFW] Shibari Outfit (By shades2jad3d)
  30. [NSFW] Cyber Harness (By shades2jad3d)
  31. [NSFW] Leather Catsuit (By Misberave)
  32. [NSFW] Black Full Dress (By BagOfPopcorn)
  33. [NSFW] YoRHafy - Skin Suit (By kesshin7)
  34. [NSFW] YoRHafy Motivation & Resonance (By kesshin7)
  35. [NSFW] Sky Siren Air/Sky Ace (By kesshin7)
  36. [NSFW] Daily / Comfort Force (By kesshin7)
  37. [NSFW] Vamps Outfit (By roybjensen)
  38. [NSFW] Eve Uniform (By Reverse7R)
  39. [NSFW] Revealing Planet Diving Suit 2nd (By songeda)
  40. [NSFW] Shadow Kunoichi (By songeda)
  41. [NSFW] Transparent Silver Kunoichi (By songeda)
  42. [NSFW] Transparent Santa (By songeda)
  43. [NSFW] Transparent Elegant Dress (By songeda)
  44. [NSFW] Fishnet Midsummer (By songeda)
  45. [NSFW] Revealing Black Dress (By songeda)
  46. [NSFW] Guilded Rose Dress (By pLastGhost)
  47. [NSFW] Motified Neurolink Suit (By zealot9999)
  48. [NSFW] Cake Unveiled Cooling Suit (By briefcasesharpie)
- GET YOUR MOD LISTED HERE!! (leave a comment with a link to your mod, or the mod id)

Compatible Faces: 
Female NPC Faces (By 4H3y9fjbb89BKjI)

Compatible Hairs: 
Raven Hair (By kesshin7)

Compatible Default Skins: 
Note: These are not custom skins, but are compatible json files to show default outfits within the CNS menu. 
  1. Fusion suit (By QueenEri)
  2. Silver & Shadow Kunoichi (ByQueenEri)
CNS - Female NPC Faces 可以方便換臉, 有 Tachy, Scarlet, Raven, Lily's 可以切換, 搭配 Raven 頭髮 CNS mod, 可以方便變出 Raven。

目前大部分都改用 CNS mod, 替換服裝的 mod 用起來太不方便。不過 CNS mod 有個缺點, 換好的服裝在設定畫面時, 不會跟著顯示, 設定畫面顯示的衣服是從設定畫面選的服裝, 有點可惜。

First Descendant Bunny Apex Predator 這套蠻好看

裝好之後, 按下 n 就可以開啟換裝界面, 使用滑鼠換裝, 在 steam deck 上操作還真難倒我, steam 按鍵 + x, 開啟虛擬鍵盤, 建議裝個藍芽鍵盤比較輕鬆。



tifa 衣服應該是蠻受歡迎的, 不過我卻不是很想用這個 mod, 又不是在玩 ff7, 用這個 mod 我乾脆玩 ff7 就好了, 所以拖到支援 cns 時, 我才用這個 mod, tifa hair and earring for eve-1567-1-0-1753177974 新版本有支援 cns, tifa 衣服也有 cns, 因為很容易就可以更換, 就裝了。

光頭效果是因為 TIFA HAIR WITH ENHANCED PHYSICS-1681-1-0-1753717159.zip 引起的, 建議用 tifa hair and earring for eve-1567-1-0-1753177974。













明末淵虛之羽和古墓奇兵, DOA, TIFA, The First Descendant 都來了, 感覺玩了好幾款遊戲。

cns-1.9 之後, 也可以更換 lily, adam 的服飾, 相當方便。

20250827 出了 CNS Repacker mod, 這個 mod 可以把非 cns mod 轉成 cns mod,好神奇。

需要 ".NET 8.0 Desktop Runtime", 我就怕這個, 在 steam deck, 我不知道怎麼把 .net 搞定。

奇怪, 討論區說需要 ".NET 8.0 Desktop Runtime", 但我看 Source code https://gitlab.com/DeronFer/cnsrepacker 這是用 kotlin 寫的, 嘗試在 linux 下編譯。
in linux compile
gradle/wrapper/gradle-wrapper.properties:4:distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
download
gradle-8.14.3-bin.zip

改成下載的 path
gradle/wrapper/gradle-wrapper.properties:4:distributionUrl=file:///home/descent/work-2/mod/cnsrepacker/gradle-8.14.3-bin.zip

download graalvm-jdk-24_linux-x64_bin.tar.gz

編譯成 linux native 執行檔
export JAVA_HOME=$PWD
export PATH=$JAVA_HOME/bin:$PATH

編譯
./gradlew nativeCompile

經歷這些磨難之後, 成功之後, 執行檔案在 cnsrepacker/build/native/nativeCompile/CNSRepacker

執行結果:
descent@deb64:cnsrepacker$ /media/work-2/mod/cnsrepacker/build/native/nativeCompile/CNSRepacker
The folder /media/work-2/mod/cnsrepacker/./../SB/Content/Paks doesn't exist. Make sure that you use a correct path to the game.

CNSRepacker 會呼叫以下2個執行檔
./tools/retoc/retoc.exe
./tools/UAssetGUI/UAssetGUI.exe
這 2 個檔案是 windows 執行檔, 建議還是在 windows 執行 CNSRepacker 會比較容易, 不確定 wine 能不能正常執行 ./tools/retoc/retoc.exe, ./tools/UAssetGUI/UAssetGUI.exe
[CNSRepacker 測試]

由於需要在 windows 執行 CNSRepacker.exe 我把 steam deck 的劍星目錄複製到 windows k: 下, 把 CNSRepacker 放在和 SB 同一層目錄, 以我的例子就是: K:\StellarBlade\CNSRepacker, 參考 list 1。

list 1. CNSRepacker 路徑
1 .
2 ├── CNSRepacker
3 ├── crs-client.dll
4 ├── crs-handler.exe
5 ├── crs-uploader.exe
6 ├── Engine
7 ├── SB
8 ├── SB.exe
9 └── Screenshots

執行 CNSRepacker.exe 之前, CNS mod 要先安裝好, 猜測 CNSRepacker 可能會用到 CNS mod 的檔案。

不確定要不要安裝 ".NET 8.0 Desktop Runtime", 我是有安裝 ".NET 8.0 Desktop Runtime" x64 版本, 可以先不要安裝, 等轉換失敗再來安裝。

用這個非 CNS mod EveChaHae-In-2014-1-0-1756957570 來測試。解壓縮 EveChaHae-In-2014-1-0-1756957570 放到 \CNSRepacker\ToRepack, 以我的例子來說就是: K:\StellarBlade\CNSRepacker\ToRepack\EveChaHae-In-2014-1-0-1756957570, 參考 list 2。

list 2. 要轉的 EveChaHae mod 路徑
 1 CNSRepacker
 2 ├── alreadyRepacked.txt
 3 ├── CNSRepacker.exe
 4 ├── config.txt
 5 ├── data
 6 │   ├── assetToImportAsset.txt
 7 │   ├── assetToRootAsset.txt
 8 │   ├── excludedAssets.txt
 9 │   └── rootAssetToInfo.txt
10 ├── log.txt
11 ├── tools
12 │   ├── retoc
13 │   └── UAssetGUI
14 └── ToRepack
15     └── EveChaHae-In-2014-1-0-1756957570
16 
17 6 directories, 8 files

點擊 CNSRepacker.exe

CNSRepacker.exe 執行期間, 會去執行以下指令:
"tools\retoc\retoc.exe" "to-legacy" "--mount-folder" "K:\StellarBlade\CNSRepacker\.\..\SB\Content\Paks" "C:\Users\ADMINI~1\AppData\Local\Temp\StellarBladeCNSRepacker\modCopy" "C:\Users\ADMINI~1\AppData\Local\Temp\StellarBladeCNSRepacker\modExtracted" "--no-ver-check" "--check-subfolders"
注意這2個目錄, CNSRepacker.exe 執行期間會需要這2個目錄, 在我的平台上, 這 2 個目錄會被移除, 造成 "tools\retoc\retoc.exe" 執行失敗, 我是手動建立這2個目錄, 開啟 2個 cmd dos 視窗, 進入這2個目錄, 這樣以下 2 個目錄就不會被移除。
C:\Users\Administrator\AppData\Local\Temp\StellarBladeCNSRepacker\modExtracted
C:\Users\Administrator\AppData\Local\Temp\StellarBladeCNSRepacker\modCopy
如果執行失敗, 可以看一下 CNSRepacker\log.txt, 會描述一些失敗的原因。

成功的話, 被轉成 CNS 版本的 mod 會放在
K:\StellarBlade\SB\Content\Paks\~mods\CustomNanosuitSystem\Repacked\EveChaHae-In-2014-1-0-1756957570

看一下被轉換後的內容, 多了一個 EveChaHae-In-2014-1-0-1756957570.dekcns.json, 0d353c86d941d1f6.ucas 檔案還變小。
2025/09/08  下午 11:35             3,767 0d353c86d941d1f6.utoc
2025/09/08  下午 11:35        11,750,559 0d353c86d941d1f6.ucas
2025/09/08  下午 11:35               347 0d353c86d941d1f6.pak
2025/09/08  下午 11:35               816 EveChaHae-In-2014-1-0-1756957570.dekcns.json
原本 EveChaHae-In-2014-1-0-1756957570 mod 的內容:
2025/09/03  上午 09:17               339 EveChaHae-In_P.pak
2025/09/03  上午 09:17        22,812,928 EveChaHae-In_P.ucas
2025/09/03  上午 09:17             5,759 EveChaHae-In_P.utoc
list 3 為 CNSRepacker.exe 成功轉換的結果, 大多數「梅川伊芙」mod 都沒 cns 版本, 轉成 cns 之後, 就非常方便。

list 3. CNSRepacker.exe 執行畫面
 1 K:\StellarBlade>cd CNSRepacker
 2 
 3 K:\StellarBlade\CNSRepacker>CNSRepacker.exe
 4 Found 1 folders inside K:\StellarBlade\CNSRepacker\.\ToRepack
 5 
 6 1/1 RetexEve-DarkInnerSuit-Version 2-141-2-1749404375 ............................................... SUCCESS
 7 Press Enter to exit...
 9 
10 K:\StellarBlade\CNSRepacker>CNSRepacker.exe
11 Found 1 folders inside K:\StellarBlade\CNSRepacker\.\ToRepack
12 
13 1/1 Skin Suit alternate-261-1-0-1749813978 .......................................................... SUCCESS
14 Press Enter to exit...
16 
17 K:\StellarBlade\CNSRepacker>CNSRepacker.exe
18 Found 1 folders inside K:\StellarBlade\CNSRepacker\.\ToRepack
19 
20 1/1 SB_NudeInnerSuit-13-1-1-1748881015 .............................................................. SUCCESS
21 Press Enter to exit...
23 
24 K:\StellarBlade\CNSRepacker>CNSRepacker.exe
25 Found 1 folders inside K:\StellarBlade\CNSRepacker\.\ToRepack
26 
27 1/1 Makeup Only-33-1-1749408865 ..................................................................... SUCCESS
28 Press Enter to exit...

以下影片顯示轉成 CNS 的 EveChaHae mode。



也可以轉化妝的模組, 透過 cns 更換化妝模組非常方便。 服裝修改的模組也可以轉成 cns, 原本的服裝和被修改過的版本都可以同時存在。

SailorSkirt 這個 mod 我本來無法成功使用, 轉成 cns mod 之後, 就可以正常使用。



Valretos Divine Punishment 這個 mod 也是無法正常使用, 轉成 cns 版本就可以用了。

2025年8月26日 星期二

安裝 劍星 ue4ss mod

20250723 才知道有個叫做 UE4SS 的 mod, 這個 mod 很特別, 並不是提供遊戲功能, 而是提供一個修改界面, 讓開發人員可以用 UE4SS 來修改遊戲, 但我不知道這和原本的 mod 修改有什麼不同, 也許是可以提供更不同的修改內容。steam deck 一樣可以使用 ue4ss。

ue4ss 是很重要的底層 mod, 建議還是裝起來, 很多有趣的 mod 都會需要 ue4ss, 雖然有時候會造成遊戲不穩開不起來, 但是還是值得使用, 通常是更新才會遇到遊戲不穩開不起來的情形。

UE4SS 3.1.0 for StellarBlade 在 20250723 使用 UE4SS 需要使用 UE4SS_v3.1.0-6.zip 這個版本, 否則會遇到無法載入 UE4SS.dll 錯誤訊息, 應該是劍星更新的問題。UE4SS_v3.1.0-6 這是 fork UE4SS 專門針對劍星的修改。



Camera Control, 就是一個透過 ue4ss 修改的 mod, 可以調整相機視角, 但我覺得不太好用, 有點過頭, 會看到一些非遊戲場景的角度。

ue4ss mod 要放在 steam deck 路徑: /home/deck/.local/share/Steam/steamapps/common/StellarBlade/SB/Binaries/Win64/

list 2. ue4ss 目錄結構 (/home/deck/.local/share/Steam/steamapps/common/StellarBlade/SB/Binaries/Win64/)
 1 .
 2 ├── dwmapi.dll
 3 └── ue4ss
 4     ├── Default_UVTD_Configs
 5     ├── LICENSE
 6     ├── Mods
 7     ├── UE4SS.dll
 8     ├── UE4SS-settings.ini
 9     ├── UE4SS_Signatures
10     └── VTableLayout.ini
11
12 4 directories, 5 files

dwmapi.dll 是一個 dll hook, 遊戲會載入 dwmapi.dll, dwmapi.dll 會載入 UE4SS.dll, 載入成功會看到 UE4SS.log, 裡頭會紀錄一些載入的 mod 資訊。

list 3. UE4SS.log
  1 [2025-07-24 15:08:46.2759360] Console created
  2 [2025-07-24 15:08:46.2761107] UE4SS - v3.0.1 Beta #0 - Git SHA #d3d1004
  3 [2025-07-24 15:08:46.2761234] UE4SS Build Configuration: Game__Shipping__Win64 (MSVC)
  4 [2025-07-24 15:08:46.2868598] Creating save backup
  5 [2025-07-24 15:08:46.4882794] Setting up mods...
  6 [2025-07-24 15:08:46.4989272] Starting mods (from mods.txt load order)...
  7 [2025-07-24 15:08:46.4997833] Starting mods (from enabled.txt, no defined load order)...
  8 [2025-07-24 15:08:46.5026510] No specific game configuration found, using default configuration file
  9 [2025-07-24 15:08:46.5026787] Config: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss\UE4SS-settings.ini
 10 
 11 [2025-07-24 15:08:46.5026866] root directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss
 12 [2025-07-24 15:08:46.5026936] working directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss
 13 [2025-07-24 15:08:46.5027003] game executable directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64
 14 [2025-07-24 15:08:46.5027447] game executable: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\SB-Win64-Shipping.exe (324622336 bytes)
 15 
 16 
 17 [2025-07-24 15:08:46.5027521] mods directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss\Mods
 18 [2025-07-24 15:08:46.5027585] log directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss
 19 [2025-07-24 15:08:46.5027651] object dumper directory: Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss
 20 
 21 
 22 [2025-07-24 15:08:46.5131256] Getting ordered lists from ini file
 23 [2025-07-24 15:08:46.5131786] UObjectBase

949 
950 [2025-07-24 15:08:52.4567664] m_shared_functions: 0x1cebeb0
951 [2025-07-24 15:08:52.4583826] Input source set to: Win32Async
952 [2025-07-24 15:08:52.4938174] Enabling custom events
953 [2025-07-24 15:08:52.4944210] Starting mods (from mods.txt load order)...
954 [2025-07-24 15:08:52.4949094] Starting Lua mod 'JiggleUpdate'
955 [2025-07-24 15:08:52.4980764] [Lua] [Patch] Loaded tweaks from Z:\home\deck\.local\share\Steam\steamapps\common\StellarBlade\SB\Binaries\Win64\ue4ss\Mods\JiggleUpdate\scripts\SpringBoneTweaks.lua[2025-07-24 15:08:52.5099139] [Lua] [CDO] Total patched: 0[2025-07-24 15:08:52.5215790] [Lua] [CDO] Total patched: 0[2025-07-24 15:08:52.5291171] [Lua] [Patch] Live instance not found for 'CharacterMesh0.CH_P_EVE_01_AnimBP_New_C'[2025-07-24 15:08:52.5341072] [Lua] [Patch] Live instance not found for 'Mesh_Body.CH_P_EVE_01_AnimBP_Studio_C'[2025-07-24 15:08:52.5341845] Starting Lua mod 'CheatManagerEnablerMod'

956 [2025-07-24 15:08:52.5371595] [RegisterHook] Registered native hook (1, 2) for Function /Script/Engine.PlayerController:ClientRestart
957 [2025-07-24 15:08:52.5372308] Mod 'ActorDumperMod' disabled in mods.txt.
958 [2025-07-24 15:08:52.5372393] Starting Lua mod 'ConsoleCommandsMod'
959 [2025-07-24 15:08:52.5459782] Starting Lua mod 'ConsoleEnablerMod'
960 [2025-07-24 15:08:52.5509616] [RegisterHook] Registered native hook (3, 4) for Function /Script/Engine.PlayerController:ClientRestart
961 [2025-07-24 15:08:52.5510278] Mod 'SplitScreenMod' disabled in mods.txt.
962 [2025-07-24 15:08:52.5510372] Starting Lua mod 'LineTraceMod'
963 [2025-07-24 15:08:52.5568042] [Lua] [LineTraceMod] KismetSystemLibrary: KismetSystemLibrary /Script/Engine.Default__KismetSystemLibrary
964 [2025-07-24 15:08:52.5589013] [Lua] [LineTraceMod] KismetMathLibrary: KismetMathLibrary /Script/Engine.Default__KismetMathLibrary
965 [2025-07-24 15:08:52.5589718] Starting Lua mod 'BPML_GenericFunctions'
966 [2025-07-24 15:08:52.5604039] Starting Lua mod 'BPModLoaderMod'
967 [2025-07-24 15:08:52.6100073] [Lua] [BPModLoaderMod] Mods/BPModLoaderMod/load_order.txt not present or no matching mods, loading all BP mods in random order.
968 [2025-07-24 15:08:52.6100615] [Lua] [BPModLoaderMod] SBGhostMOD_P == table: 000000002FF6A3E0
969 [2025-07-24 15:08:52.6100700] [Lua] [BPModLoaderMod]     AssetName == ModActor_C
970 [2025-07-24 15:08:52.6100843] [Lua] [BPModLoaderMod]     AssetPath == /Game/Mods/SBGhostMOD_P/ModActor
971 [2025-07-24 15:08:52.6100926] [Lua] [BPModLoaderMod]     AssetNameAsFName == FNameUserdata: 000000002FF358C8
972 [2025-07-24 15:08:52.6100989] [Lua] [BPModLoaderMod]     Name == SBGhostMOD_P
973 [2025-07-24 15:08:52.6102492] Mod 'jsbLuaProfilerMod' disabled in mods.txt.
974 [2025-07-24 15:08:52.6102653] Starting Lua mod 'Keybinds'
975 [2025-07-24 15:08:52.6121353] Starting mods (from enabled.txt, no defined load order)...
976 [2025-07-24 15:08:52.6139964] Event loop start
977 [2025-07-24 15:08:54.3751828] [Lua] ConsoleClass, GameViewport, or ViewportConsole is invalid
978 [2025-07-24 15:08:54.3845615] [Lua] [BPModLoaderMod] Loading mod: SBGhostMOD_P
979 [2025-07-24 15:08:54.4007457] [Lua] [BPModLoaderMod] Actor: ModActor_C /Temp/Untitled_0.Untitled:PersistentLevel.ModActor_C_2147482582
980 [2025-07-24 15:08:55.6963228] [Lua] [CheatManager Creator] Constructed CheatManager [0x88DB7100]
981 [2025-07-24 15:08:55.6963806] [Lua] [CheatManager Creator] Enabled CheatManager
982 [2025-07-24 15:08:55.6988661] [Lua] [ConsoleEnabler] ConsoleKey[1]: Tilde
983 [2025-07-24 15:08:55.6989257] [Lua] [ConsoleEnabler] ConsoleKey[2]: F10
984 [2025-07-24 15:08:55.7002445] Unregistering native pre-hook (3) for /Script/Engine.PlayerController:ClientRestart
985 [2025-07-24 15:08:55.7002824] Unregistering native post-hook (4) for /Script/Engine.PlayerController:ClientRestart
986 [2025-07-24 15:08:55.8420784] [Lua] [BPModLoaderMod] Loading mod: SBGhostMOD_P
987 [2025-07-24 15:08:55.8870605] [Lua] [BPModLoaderMod] Actor: ModActor_C /Game/Lobby/Lobby.LOBBY:PersistentLevel.ModActor_C_2147482471

用 ue4ss 做的 mod, 就是放在 ue4ss/Mods, Camera Control mod 就是放在這。

另外還有放在 /home/deck/.local/share/Steam/steamapps/common/StellarBladeDemo/SB/Content/Paks/LogicMods, CNS mod 就放在這。

ue4ss 裝好有個 JiggleUpdate mod, 成功啟用的話, 就可以在 list 3 L954 ~ L955 看到載入 JiggleUpdate, 這個是加強抖動效果。

2025年8月25日 星期一

劍星 跳極樂淨土舞蹈 mod

Garnidelia - Gokuraku Jodo Motion with Music mod 是一個很特別的 mod, 可以讓 Eve 跳極樂淨土舞蹈, 當然, 這時候無法進行遊戲, 單純看 eve 跳舞, 安裝過程複雜了一些, 不過是值得的。

Gokuraku Jodo Motion with Music mod 需要先安裝以下 mod:
  1. MyAnimsJiggleMod
  2. toggledev.vbs
  3. ue4ss
ue4ss 是很重要的底層 mod, 就算不用這個 mod, 建議還是裝起來, 很多有趣的 mod 都會需要 ue4ss, 雖然有時候會造成遊戲不穩開不起來, 但是還是值得使用, 通常是更新才會遇到遊戲不穩開不起來的情形。

參考: 安裝劍星 ue4ss mod

toggledev.vbs (這是一個 vb script, 看起來只是修改 UE4SS-settings.ini) 放到 StellarBlade\SB\Binaries\Win64\ue4ss\

AnimJiggleAdd_P (MyAnimsJiggleMod 作者提供的抖動效果 mod, 不一定要安裝, 抖動效果不同而已) 放到 StellarBlade\SB\Content\Paks\~mods

Adictional activation key F1-1802-2025-1755124067.rar (Gokuraku Jodo Motion with Music mod) 解開放到 StellarBlade\SB\Content\Paks\LogicMods\Gokurakujodo_P

adictional file-1802-2025-1754979161.rar 這是作者未來會用到的檔案, 我目前沒裝這個檔案。

照著 list 1. L15 ~ L37 ue4sssettings.ini 的設定, 修改 ue4sssettings.ini。

toggledev.vbs
 1 Dim fso, file, lines, path, line, out, i
 2 Set fso = CreateObject("Scripting.FileSystemObject")
 3 
 4 path = "UE4SS-settings.ini"
 5 Set file = fso.OpenTextFile(path, 1, False)
 6 lines = Split(file.ReadAll, vbCrLf)
 7 file.Close
 8 
 9 For i = 0 To UBound(lines)
10     line = lines(i)
11     If InStr(line, "ConsoleEnabled = 0") Then
12         lines(i) = Replace(line, "0", "1")
13     ElseIf InStr(line, "ConsoleEnabled = 1") Then
14         lines(i) = Replace(line, "1", "0")
15     ElseIf InStr(line, "GuiConsoleEnabled = 0") Then
16         lines(i) = Replace(line, "0", "1")
17     ElseIf InStr(line, "GuiConsoleEnabled = 1") Then
18         lines(i) = Replace(line, "1", "0")
19     ElseIf InStr(line, "GuiConsoleVisible = 0") Then
20         lines(i) = Replace(line, "0", "1")
21     ElseIf InStr(line, "GuiConsoleVisible = 1") Then
22         lines(i) = Replace(line, "1", "0")
23     ElseIf InStr(line, "bUseUObjectArrayCache = false") Then
24         lines(i) = Replace(line, "false", "true")
25     ElseIf InStr(line, "bUseUObjectArrayCache = true") Then
26         lines(i) = Replace(line, "true", "false")
27     End If
28 Next
29 
30 Set out = fso.OpenTextFile(path, 2, False)
31 For i = 0 To UBound(lines)
32     out.WriteLine lines(i)
33 Next
34 out.Close
35 
36 MsgBox "Settings toggled", 64, "Done"


list 1. 節錄 Garnidelia - Gokuraku Jodo Motion with Music mod 安裝說明
 1 Motion mod that makes Eve dances Gokuraku Jodo from Garnidelia requires UE4SS
 2 
 3 Motion actvation by keyboard Num.5
 4 
 5 Added a file version with F1 key activation for those who don't have numeric keyboard
 6 
 7 Installation folder >>> LogicMods
 8 
 9 how installation path have to look be : StellarBlade\SB\Content\Paks\LogicMods\Gokurakujodo_P
10 
11 
12 For jiggle physics use my jiggle mod: https://www.nexusmods.com/stellarblade/mods/1871
13 
14 In your ue4sssettings.ini have sure these parameters are this way:
15 [Debug]
16 ; Whether to enable the external UE4SS debug console.
17 ConsoleEnabled = 1
18 GuiConsoleEnabled = 1
19 GuiConsoleVisible = 1
20 
21 ; The API that will be used to render the GUI debug window.
22 ; Valid values (case-insensitive): dx11, d3d11, opengl
23 ; Default: opengl
24 GraphicsAPI = dx11
25 
26 [Hooks]
27 HookProcessInternal = 1
28 HookProcessLocalScriptFunction = 1
29 HookInitGameState = 1
30 HookLoadMap = 1
31 HookCallFunctionByNameWithArguments = 1
32 HookBeginPlay  = 0
33 HookLocalPlayerExec = 1
34 HookAActorTick = 1
35 HookEngineTick = 1
36 HookGameViewportClientTick = 1
37 FExecVTableOffsetInLocalPlayer = 0x28
38 
39 Download the toggledev.vbs and place it on your eu4ss folder this way : StellarBlade\SB\Binaries\Win64\ue4ss
40 
41 The mod have the music so let it play till the end :v cause it dont stop if you stops the dance(idk how to make a control to music stops, only to play XD)
42 
43 link of the ue4ss version that i using:
44 
45 Ue4Ss that i using
46 
47 https://github.com/Chrisr0/RE-UE4SS/releases


裝好之後按下最右邊的數字按鍵 5, 就可以發動跳舞功能, 如果沒有數字按鍵的鍵盤, 也可以按下 F1 觸發。



由於可以搭配 cns 使用, 弄了蕾雯的版本, 蕾雯飄逸的長髮還蠻特別。



按下 F1 開始跳舞, 再次按下 F1 會停止, 但是極樂淨土音樂會持續播放到結束, 作者還不知道怎麼中斷音樂, 也許之後的版本會改善。跳舞期間可以移動視角, 看看不同的角度。



在跳舞的狀態下, 如果被怪物襲擊, 也是會被打死的, 另外操作人物摔下懸崖一樣會死。



2025年8月20日 星期三

pc9801 rusty 中文化

Reputation is currency. Relationships are long-term leverage.
pc9801 的日文編碼是「Shift-JIS」, 找出「ゲームスタート」的「Shift-JIS」編碼, 在 JO.EXE 執行檔內尋找, 再把「遊戲開始」的「Shift-JIS」編碼找出, 改成這個「遊戲開始」的「Shift-JIS」編碼, 剩下的部份用 0x00 覆蓋。

list 1. ゲームスタート
1descent@deb64:hdi$ echo "ゲームスタート" | iconv -f UTF-8 -t SHIFT-JIS > s2.jis
2 descent@deb64:hdi$ hexdump -C s2.jis
3 00000000  83 51 81 5b 83 80 83 58  83 5e 81 5b 83 67 0a
4 0000000f

...

7 descent@u64:bjd$ echo "遊戲開始" | iconv -f UTF-8 -t SHIFT-JIS > s2.jis
8 descent@u64:bjd$ hexdump -C s2.jis
9 00000000  97 56 9d 45 8a 4a 8e 6e  0a


把 list 2 的藍色換成紅色部份的數字, 就完成了「ゲームスタート」的中文化, 使用的是日文漢字, 並不是 big5/unicode 的中文編碼。

list 2. JO.EXE
00006C30  00 00 00 83  51 81 7C 83   80 83 58 83  5E 81 7C 83
00006C40  67 00 83 52  83 93 83 65   83 42 83 6A  83 85 81 7C 

...

00006C30  00 00 00 97  56 9D 45 8A   4A 8E 6E 00  00 00 00 00
00006C40  00 00 E3 8B  E3 94 97 56   9D 45 00 00  00 00 00 00
fig 1. dos/v 日文版
fig 2. pc9801 日文版本改為中文
另外還有遊戲劇情的部份, 這邊我就沒有任何想法, 不知道怎麼下手, 一堆檔案根本不知道怎麼分析。看了「夜行侦探 EVE burst error 中文化分析」這系列, 還是沒什麼頭緒, 好難。

2025年8月7日 星期四

讀取 jpeg 圖片, 本來以為是透明效果, 不過這個好像是漸層效果顯示, 另外實做了透明效果。

fig 1. 棄捐勿復道, 努力加餐飯。
這是我在 2002 寫的程式, 對透明色處理有興趣, 想自己寫出來, 找了很久, 忘記在哪本書看到這個演算法, 透過 linux/sgvalib 實做出來, 寫出來時還蠻開心的, 那時候用的版本控制軟體是 rcs。

對於電腦繪圖方式有興趣, 研究了 vga 模式和圖形顯示的原理, 如果用 qt 之類的, 很容易就可以完成秀出一張圖片的功能, 甚至還可以作到縮放, 但我想多知道一些, 就研究了這些技術, 大部分是從 dos 時代的繪圖相關書籍學習。

2002 沒有 chatgpt, 光是使用 jpeg lib 就難倒我, 啃著英文文件, 也不知道有沒看懂, 硬是讓我成功解出 jpeg 內容, 現在有 chatgpt, 應該秒會用吧!

在 20250804 想到 pc9801 遊戲 16 色時突然想到這個, 把這程式以 framebuffer 重新改寫, 沒辦法, svgalib 可能沒辦法在現今的平台執行, 呈現的效果看起來還蠻像一回事。

重新檢視演算法, 並沒有和背景色做運算, 我傻眼, 這好像不是透明演算法。問了 chatgpt 這個演算法, 還真的不是, chatgpt 說這是漸層演算法, 整整搞錯 23 年。



framebuffer 繪圖則是問 chatgpt, 節省不少時間。

由於在螢幕上顯示圖形非常複雜, 需要理解 vga 顯示模式和影像格式, 我挑了最簡單的方式做, 在 640x480 24bit color 上顯示 24bit jpeg 圖檔, 可以避開 Quantization + Dithering 的問題, 現在有 chatgpt, 比較容易找到這 2 個演算法, 23 年科技進步的太大了。

在 2025 年, 這些技術也不需要, 2025 年應該不會有 256 色的顯示模式了。



透明色公式是:
final = src_color * alpha + background_color * (1 - alpha);

重新挑戰透明色, 麻煩的是要怎麼取得背景圖, 就先不處理這個, 直接拿2張圖做透明計算。

list 1. fb-jpeg.cpp
  1 /*
  2  *
  3  * $Author: descent $
  4  * $Date: 2002/06/20 02:55:23 $
  5  * $Id: jpeg.cpp,v 1.2 2002/06/20 02:55:23 descent Exp descent $
  6  * $Revision: 1.2 $
  7  * 程式功能:用 jpeg library 來讀取 jpeg 圖檔,改用 framebuffer 來秀圖
  8  * 	     並加入XX效果。
  9  */
 10 
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <fcntl.h>
 14 #include <linux/fb.h>
 15 #include <sys/mman.h>
 16 #include <sys/ioctl.h>
 17 #include <unistd.h>
 18 #include <string.h>
 19 #include <stdint.h>
 20 
 21 #include <vector>
 22 #include <iostream>
 23 #include <string>
 24 
 25 #include <jpeglib.h>
 26 #include <jerror.h>
 27 
 28 using namespace std;
 29 
 30 uint8_t *fbp;
 31 struct fb_var_screeninfo vinfo;
 32 struct fb_fix_screeninfo finfo;
 33 
 34 struct Color
 35 {
 36   Color (unsigned char r, unsigned char g, unsigned char b):r_ (r), g_ (g),
 37     b_ (b)
 38   {
 39   }
 40   unsigned char r () const
 41   {
 42     return r_;
 43   }
 44   unsigned char g () const
 45   {
 46     return g_;
 47   }
 48   unsigned char b () const
 49   {
 50     return b_;
 51   }
 52 private:
 53   unsigned char r_, g_, b_;
 54 };
 55 
 56 class Bitmap
 57 {
 58 public:
 59   Bitmap (int width, int height):width_ (width), height_ (height)
 60   {
 61   }
 62   void set_color (const std::vector < Color > &color)
 63   {
 64     color_ = color;
 65   }
 66   const std::vector < Color > &color_pixel () const
 67   {
 68     return color_;
 69   }
 70   int w () const
 71   {
 72     return width_;
 73   }
 74   int h () const
 75   {
 76     return height_;
 77   }
 78 private:
 79   int width_, height_;
 80   std::vector < Color > color_;
 81 };
 82 
 83 int r = 127;
 84 int g = 78;
 85 int b = 50;
 86 int color_value;
 87 
 88 void show(const Bitmap & bitmap, int x, int y, int level = 256)
 89 {
 90   //bitmap.color_pixel();
 91   std::vector < Color >::const_iterator it = bitmap.color_pixel ().begin ();
 92   //gl_getpalettecolor(color_value,&r,&g,&b);
 93   
 94   for (int i = 0; i < bitmap.h (); ++i)
 95   {
 96     usleep(1000);
 97     for (int j = 0; j < bitmap.w (); ++j)
 98     {
 99       //gl_setpixelrgb(x+j,y+i,(*it).r()*level/256,(*it).g()*level/256,(*it).b()*level/256);
100       int pix_r = (*it).r ();
101       int pix_g = (*it).g ();
102       int pix_b = (*it).b ();
103       //gl_setpixelrgb(x+j,y+i,r +(pix_r - r)*level/256, g +(pix_g - g)*level/256, b + (pix_b - b)*level/256);
104       //gl_setpixelrgb(x+j,y+i,pix_r*level+r*(1-level),pix_g*level+g*(1-level),pix_b*level+b*(level));
105       long location = (y+i)*finfo.line_length + (x+j) * 4; // 4 bytes per pixel
106       uint32_t *pixel = (uint32_t *)(fbp + location);
107       //printf("i: %d, j: %d, pixel: %p, fbp: %p\n", i, j, pixel, fbp);
108       #if 1
109       if (i <= 120)
110       {
111 	//gl_setpixelrgb (x + j, y + i, (*it).r (), (*it).g (), (*it).b ());
112             // 32-bit ARGB,alpha=0xFF (不透明),紅色R=0xFF, G=0x00, B=0x00
113             // 寫法是 0xAARRGGBB
114         unsigned int val = 0xff000000;
115         val |= ((*it).r() << 16);
116         val |= ((*it).g() << 8);
117         val |= (*it).b();
118 	*pixel = val;
119             //*pixel = 0xFFFF0000;
120       }
121       else
122       {
123         unsigned int val = 0xff000000;
124         val |= (((*it).r () + (r - (*it).r ()) * level / 256) << 16);
125         val |= (((*it).g () + (g - (*it).g ()) * level / 256) << 8);
126         val |= ((*it).b () + (b - (*it).b ()) * level / 256);
127 	*pixel = val;
128             //*pixel = 0xFFFF0000;
129         #if 0
130 	gl_setpixelrgb (x + j, y + i,
131 			(*it).r () + (r - (*it).r ()) * level / 256,
132 			(*it).g () + (g - (*it).g ()) * level / 256,
133 			(*it).b () + (b - (*it).b ()) * level / 256);
134         #endif
135       }
136       #endif
137       ++it;
138     }
139   }
140   //for ( ; it !=bitmap.color_pixel().end() ; ++it)
141 
142 }
143 
144 void get_hex (char c, char hex[])
145 {
146   char ascii[] = "0123456789abcdef";
147   int low = (c & 0x0f);
148   int high = ((c >> 4) & 0x0f);
149   hex[0] = ascii[high];
150   hex[1] = ascii[low];
151 }
152 
153 int main(int argc, char *argv[])
154 {
155   struct jpeg_decompress_struct cinfo;
156   struct jpeg_error_mgr jerr;
157 
158   cinfo.err = jpeg_std_error (&jerr);
159   jpeg_create_decompress (&cinfo);
160 
161   if (argc < 2)
162   {
163     cout << "Enter a file name" << endl;
164     return -1;
165   }
166 
167   string filename = argv[1];
168   FILE *infile;
169   if ((infile = fopen (filename.c_str (), "rb")) == NULL)
170   {
171     fprintf (stderr, "cann't open file");
172     return -1;
173   }
174   //int level=255;
175   //if (argc>=3)
176   //level=atoi(argv[2]);
177   jpeg_stdio_src (&cinfo, infile);
178   jpeg_read_header (&cinfo, true);
179   // set parameters fro decompress
180   //cinfo.scale_num=1;
181   //cinfo.scale_denom=2;
182   //cinfo.output_width=640;
183   //cinfo.output_height=480;
184   //cinfo.image_height=480;
185   jpeg_start_decompress (&cinfo);
186 
187   JSAMPARRAY buffer;
188   int row_stride = cinfo.output_width * cinfo.output_components;
189   int jpeg_width = cinfo.output_width;
190   buffer =
191     (*cinfo.mem->alloc_sarray) ((j_common_ptr) & cinfo, JPOOL_IMAGE,
192 				row_stride, 1);
193   JSAMPROW ptr = NULL;
194   int i = 0;
195 
196   std::vector < Color > color;
197   Bitmap bitmap (cinfo.output_width, cinfo.output_height);
198   while (cinfo.output_scanline < cinfo.output_height)
199   {
200     jpeg_read_scanlines (&cinfo, buffer, 1);
201     ptr = buffer[0];
202     //cout << "line " << ++i << " : " << endl;
203     int index = 0;
204     // scanline 是圖檔的寬度 * 顏色的數目,在 full color 一個 pixel 要三個 byte
205     //for (int col=0 ; col < cinfo.image_width * cinfo.output_components ; col++)
206     for (int col = 0; col < cinfo.image_width; col++)
207     {
208       //cout << index++ << " : GETJSAMPLE(*ptr++) : " << GETJSAMPLE(*ptr++) << endl;
209       //bitmap.push_back(GETJSAMPLE(*ptr++));
210       //gl_setpixelrgb(x+dx,y,GETJSAMPLE(*ptr)*level/256,GETJSAMPLE(*(ptr+1))*level/256,GETJSAMPLE(*(ptr+2))*level/256);
211       color.
212 	push_back (Color
213 		   (GETJSAMPLE (*ptr), GETJSAMPLE (*(ptr + 1)),
214 		    GETJSAMPLE (*(ptr + 2))));
215 
216 #ifdef DUMP_BITMAP_DATA
217       char h[2];
218       get_hex(GETJSAMPLE(*ptr), h);
219       cout << h[0] << h[1] << " ";
220       get_hex(GETJSAMPLE(*(ptr+1)), h);
221       cout << h[0] << h[1] << " ";
222       get_hex(GETJSAMPLE(*(ptr+2)), h);
223       cout << h[0] << h[1] << " ";
224     cout << endl;
225 #endif
226       //gl_setpixelrgb(x+dx,y,GETJSAMPLE(*ptr),GETJSAMPLE(*(ptr+1)),GETJSAMPLE(*(ptr+2)));
227       //dx++;
228       ptr += 3;
229     }
230     //dx=0;
231     //y++;
232 #ifdef DUMP_BITMAP_DATA
233     cout << endl;
234 #endif
235   }
236   bitmap.set_color (color);
237   //vga_setmode(TEXT);
238   int color_components = cinfo.output_components;
239   //cout << "cinfo.output_components : " << cinfo.output_components << endl;
240   jpeg_finish_decompress (&cinfo);
241   jpeg_destroy_decompress (&cinfo);
242 
243   fclose (infile);
244 
245 
246 
247 
248     int fb_fd = open("/dev/fb0", O_RDWR);
249     if (fb_fd == -1) {
250         perror("open fail");
251         return 1;
252     }
253 
254 
255     if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
256         perror("FBIOGET_FSCREENINFO");
257         close(fb_fd);
258         return 1;
259     }
260 
261     if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
262         perror("FBIOGET_VSCREENINFO");
263         close(fb_fd);
264         return 1;
265     }
266 
267     printf("Resolution: %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
268 
269     if (vinfo.bits_per_pixel != 32) {
270         fprintf(stderr, "This program only supports 32-bit framebuffer.\n");
271         close(fb_fd);
272         return 1;
273     }
274 
275     long screensize = vinfo.yres * finfo.line_length;
276     fbp = (uint8_t *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
277     if (fbp == MAP_FAILED) {
278         perror("mmap");
279         close(fb_fd);
280         return 1;
281     }
282 
283     printf("load jpg\n");
284 
285     int square_x = 300;
286     int square_y = 300;
287     int size = 80;
288     show(bitmap, 300, 200, 100);
289 
290 
291 #if 0
292     for (int y = 0; y < size; y++) {
293         for (int x = 0; x < size; x++) {
294             int px = square_x + x;
295             int py = square_y + y;
296 
297             long location = py * finfo.line_length + px * 4; // 4 bytes per pixel
298 
299             // 32-bit ARGB,alpha=0xFF (不透明),紅色R=0xFF, G=0x00, B=0x00
300             // 寫法是 0xAARRGGBB
301             uint32_t *pixel = (uint32_t *)(fbp + location);
302             *pixel = 0xFFFF0000;
303         }
304     }
305     #endif
306 
307     munmap(fbp, screensize);
308     close(fb_fd);
309 
310     return 0;
311 }

拜 chatgpt 之強大, 透明效果沒花太多時間就完成, 這次應該就是透明效果了, 需要用底圖來計算。



list 2. fb-tran.cpp
  1 /*
  2  *
  3  * $Author: descent $
  4  * $Date: 2002/06/20 02:55:23 $
  5  * $Id: jpeg.cpp,v 1.2 2002/06/20 02:55:23 descent Exp descent $
  6  * $Revision: 1.2 $
  7  * 程式功能:用 jpeg library 來讀取 jpeg 圖檔,改用 framebuffer 來秀圖
  8  * 	     並加入透明效果。
  9  */
 10 
 11 #include <stdio.h>
 12 #include <stdlib.h>
 13 #include <fcntl.h>
 14 #include <linux/fb.h>
 15 #include <sys/mman.h>
 16 #include <sys/ioctl.h>
 17 #include <unistd.h>
 18 #include <string.h>
 19 #include <stdint.h>
 20 
 21 #include <vector>
 22 #include <iostream>
 23 #include <string>
 24 
 25 #include <jpeglib.h>
 26 #include <jerror.h>
 27 
 28 using namespace std;
 29 
 30 uint8_t *fbp;
 31 struct fb_var_screeninfo vinfo;
 32 struct fb_fix_screeninfo finfo;
 33 
 34 struct Color
 35 {
 36   Color (unsigned char r, unsigned char g, unsigned char b):r_ (r), g_ (g),
 37     b_ (b)
 38   {
 39   }
 40   unsigned char r () const
 41   {
 42     return r_;
 43   }
 44   unsigned char g () const
 45   {
 46     return g_;
 47   }
 48   unsigned char b () const
 49   {
 50     return b_;
 51   }
 52 private:
 53   unsigned char r_, g_, b_;
 54 };
 55 
 56 class Bitmap
 57 {
 58 public:
 59   Bitmap(int width, int height):width_ (width), height_ (height)
 60   {
 61   }
 62   Bitmap():width_ (0), height_ (0)
 63   {
 64   }
 65   void set_w_h(int w, int h)
 66   {
 67     width_ = w;
 68     height_ = h;
 69   }
 70   void set_color (const std::vector < Color > &color)
 71   {
 72     color_ = color;
 73   }
 74   const std::vector < Color > &color_pixel () const
 75   {
 76     return color_;
 77   }
 78   int w () const
 79   {
 80     return width_;
 81   }
 82   int h () const
 83   {
 84     return height_;
 85   }
 86 private:
 87   int width_, height_;
 88   std::vector < Color > color_;
 89 };
 90 
 91 int r = 127;
 92 int g = 78;
 93 int b = 50;
 94 int color_value;
 95 
 96 //final = src_color * alpha + background_color * (1 - alpha);
 97 
 98 uint8_t alpha_blend(uint8_t fg, uint8_t bg, uint8_t alpha) {
 99     // alpha: 0~255, fg 前景, bg 背景
100     return (fg * alpha + bg * (255 - alpha)) / 255;
101 }
102 
103 void show(const Bitmap& bitmap, int x, int y, int level, const Bitmap& bg_bitmap)
104 {
105   //bitmap.color_pixel();
106   std::vector < Color >::const_iterator it = bitmap.color_pixel ().begin ();
107 
108   std::vector < Color >::const_iterator bg_it = bg_bitmap.color_pixel ().begin ();
109   printf("bitmap.h(): %d, bitmap.w(): %d\n", bitmap.h(), bitmap.w());
110   printf("bg_bitmap.h(): %d, bg_bitmap.w(): %d\n", bg_bitmap.h(), bg_bitmap.w());
111 
112   //gl_getpalettecolor(color_value,&r,&g,&b);
113   
114   for (int i = 0; i < bitmap.h (); ++i)
115   {
116     //usleep(1000);
117     for (int j = 0; j < bitmap.w (); ++j)
118     {
119       //gl_setpixelrgb(x+j,y+i,(*it).r()*level/256,(*it).g()*level/256,(*it).b()*level/256);
120       int pix_r = (*it).r ();
121       int pix_g = (*it).g ();
122       int pix_b = (*it).b ();
123 
124 
125       
126 
127       //gl_setpixelrgb(x+j,y+i,r +(pix_r - r)*level/256, g +(pix_g - g)*level/256, b + (pix_b - b)*level/256);
128       //gl_setpixelrgb(x+j,y+i,pix_r*level+r*(1-level),pix_g*level+g*(1-level),pix_b*level+b*(level));
129       long location = (y+i)*finfo.line_length + (x+j) * 4; // 4 bytes per pixel
130       uint32_t *pixel = (uint32_t *)(fbp + location);
131       //printf("i: %d, j: %d, pixel: %p, fbp: %p\n", i, j, pixel, fbp);
132 	//gl_setpixelrgb (x + j, y + i, (*it).r (), (*it).g (), (*it).b ());
133             // 32-bit ARGB,alpha=0xFF (不透明),紅色R=0xFF, G=0x00, B=0x00
134             // 寫法是 0xAARRGGBB
135         unsigned int val = 0x00000000;
136         unsigned char new_r, new_g, new_b;
137 
138         //double alpha = 0.8;
139         unsigned char alpha = 100;
140         #if 0
141         new_r = (unsigned char)((*it).r() * alpha + (*bg_it).r() *(255-alpha))/255;
142         new_b = (unsigned char)((*it).b() * alpha + (*bg_it).b() *(255-alpha))/255;
143         new_g = (unsigned char)((*it).g() * alpha + (*bg_it).g() *(255-alpha))/255;
144         #endif
145 
146         new_r = alpha_blend((*it).r(), (*bg_it).r(), alpha);
147         new_g = alpha_blend((*it).g(), (*bg_it).g(), alpha);
148         new_b = alpha_blend((*it).b(), (*bg_it).b(), alpha);
149 
150 
151         #if 0
152         new_r =  (*bg_it).r();
153         new_g =  (*bg_it).g();
154         new_b =  (*bg_it).b();
155         #endif
156 
157 
158         val |= ((*it).r() << 16);
159         val |= ((*it).g() << 8);
160         val |= (*it).b();
161 
162         unsigned int bg_val = 0x00000000;
163         bg_val |= ((*bg_it).r() << 16);
164         bg_val |= ((*bg_it).g() << 8);
165         bg_val |= (*bg_it).b();
166 
167         unsigned int final_val = 0xff000000;
168 
169         //final_val |= 0xff << 24;
170         final_val |= new_r << 16;
171         final_val |= new_g << 8;
172         final_val |= new_b;
173 
174 	*pixel = final_val;
175       #if 0
176       if (i <= 120)
177       {
178 	//gl_setpixelrgb (x + j, y + i, (*it).r (), (*it).g (), (*it).b ());
179             // 32-bit ARGB,alpha=0xFF (不透明),紅色R=0xFF, G=0x00, B=0x00
180             // 寫法是 0xAARRGGBB
181         unsigned int val = 0xff000000;
182         val |= ((*it).r() << 16);
183         val |= ((*it).g() << 8);
184         val |= (*it).b();
185 	*pixel = val;
186             //*pixel = 0xFFFF0000;
187       }
188       else
189       {
190         unsigned int val = 0xff000000;
191         val |= (((*it).r () + (r - (*it).r ()) * level / 256) << 16);
192         val |= (((*it).g () + (g - (*it).g ()) * level / 256) << 8);
193         val |= ((*it).b () + (b - (*it).b ()) * level / 256);
194 	*pixel = val;
195             //*pixel = 0xFFFF0000;
196         #if 0
197 	gl_setpixelrgb (x + j, y + i,
198 			(*it).r () + (r - (*it).r ()) * level / 256,
199 			(*it).g () + (g - (*it).g ()) * level / 256,
200 			(*it).b () + (b - (*it).b ()) * level / 256);
201         #endif
202       }
203       #endif
204       ++it;
205       if (i < bg_bitmap.h ())
206         ++bg_it;
207     }
208   }
209   //for ( ; it !=bitmap.color_pixel().end() ; ++it)
210 
211 }
212 
213 void get_hex (char c, char hex[])
214 {
215   char ascii[] = "0123456789abcdef";
216   int low = (c & 0x0f);
217   int high = ((c >> 4) & 0x0f);
218   hex[0] = ascii[high];
219   hex[1] = ascii[low];
220 }
221 
222 int jpeg_to_bitmap(const string &filename, Bitmap &bitmap)
223 {
224   struct jpeg_decompress_struct cinfo;
225   struct jpeg_error_mgr jerr;
226 
227   cinfo.err = jpeg_std_error (&jerr);
228   jpeg_create_decompress (&cinfo);
229 
230   FILE *infile;
231   if ((infile = fopen (filename.c_str (), "rb")) == NULL)
232   {
233     fprintf (stderr, "cann't open file");
234     return -1;
235   }
236   //int level=255;
237   //if (argc>=3)
238   //level=atoi(argv[2]);
239   jpeg_stdio_src (&cinfo, infile);
240   jpeg_read_header (&cinfo, true);
241   // set parameters fro decompress
242   //cinfo.scale_num=1;
243   //cinfo.scale_denom=2;
244   //cinfo.output_width=640;
245   //cinfo.output_height=480;
246   //cinfo.image_height=480;
247   jpeg_start_decompress (&cinfo);
248 
249   JSAMPARRAY buffer;
250   int row_stride = cinfo.output_width * cinfo.output_components;
251   int jpeg_width = cinfo.output_width;
252   buffer =
253     (*cinfo.mem->alloc_sarray) ((j_common_ptr) & cinfo, JPOOL_IMAGE,
254 				row_stride, 1);
255   JSAMPROW ptr = NULL;
256   int i = 0;
257 
258   std::vector < Color > color;
259   bitmap.set_w_h(cinfo.output_width, cinfo.output_height);
260   while (cinfo.output_scanline < cinfo.output_height)
261   {
262     jpeg_read_scanlines (&cinfo, buffer, 1);
263     ptr = buffer[0];
264     //cout << "line " << ++i << " : " << endl;
265     int index = 0;
266     // scanline 是圖檔的寬度 * 顏色的數目,在 full color 一個 pixel 要三個 byte
267     //for (int col=0 ; col < cinfo.image_width * cinfo.output_components ; col++)
268     for (int col = 0; col < cinfo.image_width; col++)
269     {
270       //cout << index++ << " : GETJSAMPLE(*ptr++) : " << GETJSAMPLE(*ptr++) << endl;
271       //bitmap.push_back(GETJSAMPLE(*ptr++));
272       //gl_setpixelrgb(x+dx,y,GETJSAMPLE(*ptr)*level/256,GETJSAMPLE(*(ptr+1))*level/256,GETJSAMPLE(*(ptr+2))*level/256);
273       color.
274 	push_back (Color
275 		   (GETJSAMPLE (*ptr), GETJSAMPLE (*(ptr + 1)),
276 		    GETJSAMPLE (*(ptr + 2))));
277 
278 #ifdef DUMP_BITMAP_DATA
279       char h[2];
280       get_hex(GETJSAMPLE(*ptr), h);
281       cout << h[0] << h[1] << " ";
282       get_hex(GETJSAMPLE(*(ptr+1)), h);
283       cout << h[0] << h[1] << " ";
284       get_hex(GETJSAMPLE(*(ptr+2)), h);
285       cout << h[0] << h[1] << " ";
286     cout << endl;
287 #endif
288       //gl_setpixelrgb(x+dx,y,GETJSAMPLE(*ptr),GETJSAMPLE(*(ptr+1)),GETJSAMPLE(*(ptr+2)));
289       //dx++;
290       ptr += 3;
291     }
292     //dx=0;
293     //y++;
294 #ifdef DUMP_BITMAP_DATA
295     cout << endl;
296 #endif
297   }
298   bitmap.set_color (color);
299   //vga_setmode(TEXT);
300   int color_components = cinfo.output_components;
301   //cout << "cinfo.output_components : " << cinfo.output_components << endl;
302   jpeg_finish_decompress (&cinfo);
303   jpeg_destroy_decompress (&cinfo);
304 
305   fclose (infile);
306   return 0;
307 }
308 
309 int main(int argc, char *argv[])
310 {
311   if (argc < 2)
312   {
313     cout << "Enter 2 file name" << endl;
314     return -1;
315   }
316 
317   //string filename = argv[1];
318 
319   Bitmap fg_bitmap;
320   jpeg_to_bitmap(argv[1], fg_bitmap);
321 
322   Bitmap bg_bitmap;
323   jpeg_to_bitmap(argv[2], bg_bitmap);
324 
325 
326 
327     int fb_fd = open("/dev/fb0", O_RDWR);
328     if (fb_fd == -1) {
329         perror("open fail");
330         return 1;
331     }
332 
333 
334     if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
335         perror("FBIOGET_FSCREENINFO");
336         close(fb_fd);
337         return 1;
338     }
339 
340     if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
341         perror("FBIOGET_VSCREENINFO");
342         close(fb_fd);
343         return 1;
344     }
345 
346     printf("Resolution: %dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
347 
348     if (vinfo.bits_per_pixel != 32) {
349         fprintf(stderr, "This program only supports 32-bit framebuffer.\n");
350         close(fb_fd);
351         return 1;
352     }
353 
354     long screensize = vinfo.yres * finfo.line_length;
355     fbp = (uint8_t *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
356     if (fbp == MAP_FAILED) {
357         perror("mmap");
358         close(fb_fd);
359         return 1;
360     }
361 
362     printf("load jpg\n");
363 
364     int square_x = 300;
365     int square_y = 300;
366     int size = 80;
367 
368     #if 0
369     show(bg_bitmap, 300, 200, 100, );
370     sleep(2);
371     #endif
372 
373     show(fg_bitmap, 300, 200, 100, bg_bitmap);
374     sleep(2);
375 
376 
377 #if 0
378     for (int y = 0; y < size; y++) {
379         for (int x = 0; x < size; x++) {
380             int px = square_x + x;
381             int py = square_y + y;
382 
383             long location = py * finfo.line_length + px * 4; // 4 bytes per pixel
384 
385             // 32-bit ARGB,alpha=0xFF (不透明),紅色R=0xFF, G=0x00, B=0x00
386             // 寫法是 0xAARRGGBB
387             uint32_t *pixel = (uint32_t *)(fbp + location);
388             *pixel = 0xFFFF0000;
389         }
390     }
391     #endif
392 
393     munmap(fbp, screensize);
394     close(fb_fd);
395 
396     return 0;
397 }

List 2 L98 是透明演算法。
g++ fb-tran.cpp -o fb-tran  -ljpeg



現在應該都是透過顯示卡來做透明效果, 很少會用 cpu 計算了。