summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Desktop/VillageArt.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-28 08:33:20 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-28 08:33:20 +0800
commit0e9948b7067e07875a9fe81879be0ae46664a785 (patch)
tree4c0decedfb6826d7fb26248a4dea25e41a60ffcc /src/LivingVillage.Desktop/VillageArt.fs
parentd92afbcb787eb91c4e6d001b1f0de04f0fc5813d (diff)
downloadliving-village-0e9948b7067e07875a9fe81879be0ae46664a785.tar.gz
feat(art): P33 接入 CC0 真实像素素材样板(地面+角色竖直切片)
- 修复 make-cc0-art.py 地块取样间距:packed sheet 无间距(16px pitch),旧 17px 误采错格 - 重选草地/石板格 (9,8)/(10,8)/(4,8)/(4,9),整数 2x NEAREST 重建 cc0-tiles.png - VillageArt 暴露 selectedGround/CharacterAtlasRelativePath 纯函数,保留 LV_ASSET_PACK=cc0 开关与程序绘制江南图集 fallback - 新增 AssetPackTests:图集加载尺寸、整数倍缩放、开关/回退断言 - docs/素材来源.md 记录来源/许可/sha256/构建/开关;同步 assets-and-licenses 与维护说明 P33 小节 - docs/evidence/p33-atlas-*.png 昼/夜/2x 特写/程序绘制对照(check-no-white-blocks 0 命中)
Diffstat (limited to 'src/LivingVillage.Desktop/VillageArt.fs')
-rw-r--r--src/LivingVillage.Desktop/VillageArt.fs36
1 files changed, 30 insertions, 6 deletions
diff --git a/src/LivingVillage.Desktop/VillageArt.fs b/src/LivingVillage.Desktop/VillageArt.fs
index 4faa886..9a034aa 100644
--- a/src/LivingVillage.Desktop/VillageArt.fs
+++ b/src/LivingVillage.Desktop/VillageArt.fs
@@ -544,22 +544,46 @@ module VillageArt =
else
texture
+ /// Fallback switch for the real-pixel asset pack (P33 vertical slice). When
+ /// `LV_ASSET_PACK=cc0`, the sample village swaps its ground + villager atlases for
+ /// the provenanced CC0 packs; any other value keeps the procedural Jiangnan atlases.
let useCc0Pack () : bool =
System.Environment.GetEnvironmentVariable("LV_ASSET_PACK") = "cc0"
let cc0TileAtlasRelativePath = "Assets/cc0-tiles.png"
+ // Source ground tiles are 16x16, upscaled exactly 2x to one Sim.tilePixels cell.
+ let cc0TileSourcePixels = 16
let cc0TileAtlasWidth = Sim.tilePixels * 4
+ let cc0TileAtlasHeight = Sim.tilePixels
let cc0CharacterAtlasRelativePath = "Assets/cc0-characters.png"
+ // Source Puny band is 16x24, upscaled exactly 2x to a 32x48 cell; atlas packs
+ // 5 variants x 4 directions x 6 frames.
+ let cc0CharacterSourceWidth = 16
+ let cc0CharacterSourceHeight = 24
+ let cc0CharacterCellWidth = 32
+ let cc0CharacterCellHeight = 48
+ let cc0CharacterVariantCount = 5
+ let cc0CharacterDirectionCount = 4
+ let cc0CharacterFrameCount = 6
+ let cc0CharacterAtlasWidth =
+ cc0CharacterCellWidth * cc0CharacterVariantCount * cc0CharacterDirectionCount * cc0CharacterFrameCount
+
+ /// Ground atlas selection: `Some cc0-tiles.png` when the pack is on, else `None`
+ /// so the renderer keeps its procedural Jiangnan ground as the fallback.
+ let selectedGroundAtlasRelativePath () : string option =
+ if useCc0Pack () then Some cc0TileAtlasRelativePath else None
+
+ /// Character atlas selection: real CC0 Puny sprites when the pack is on, else the
+ /// procedural Jiangnan character atlas (fallback).
+ let selectedCharacterAtlasRelativePath () : string =
+ if useCc0Pack () then cc0CharacterAtlasRelativePath else characterAtlasRelativePath
let loadTextures (device: GraphicsDevice) : ArtTextures =
let cc0 =
- if useCc0Pack () then
- Some(loadTexture device cc0TileAtlasRelativePath cc0TileAtlasWidth Sim.tilePixels)
- else
- None
- let characterPath = if useCc0Pack () then cc0CharacterAtlasRelativePath else characterAtlasRelativePath
+ selectedGroundAtlasRelativePath ()
+ |> Option.map (fun path -> loadTexture device path cc0TileAtlasWidth cc0TileAtlasHeight)
{ TileAtlas = loadTexture device worldAtlasRelativePath worldAtlasWidth worldAtlasHeight
- CharacterAtlas = loadTexture device characterPath characterAtlasWidth characterAtlasHeight
+ CharacterAtlas = loadTexture device (selectedCharacterAtlasRelativePath ()) cc0CharacterAtlasWidth cc0CharacterCellHeight
InteriorAtlas = loadTexture device interiorAtlasRelativePath interiorAtlasWidth interiorAtlasHeight
Cc0TileAtlas = cc0 }