Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
cmake -S . -B build-linux -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build-linux --target GenerateSohOtr --parallel
python3 -c 'import sys, zipfile; required={"textures/wind-waker/clouds/cloud_mae", "textures/wind-waker/clouds/cloud_naka", "textures/wind-waker/clouds/cloudtx_01", "textures/wind-waker/clouds/cloudtx_02", "textures/wind-waker/clouds/cloudtx_03"}; archive=set(zipfile.ZipFile("soh/soh.o2r").namelist()); missing=sorted(required-archive); print("Missing Sky assets: " + ", ".join(missing)) if missing else print("Verified all Sky cloud assets in soh.o2r"); sys.exit(bool(missing))'
python3 tools/ci/verify_nei_equipment_icons.py soh/soh.o2r
cp soh/soh.o2r Android/app/src/main/assets/soh.o2r
tools/ci/inject_android_renderer_shaders.sh

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/android-test-apk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Checkout Fusion
uses: actions/checkout@v4
with:
ref: soh-fusion-android
ref: ${{ github.ref }}
path: fusion
fetch-depth: 0
submodules: recursive
Expand Down Expand Up @@ -69,6 +69,7 @@ jobs:
cmake -S fusion -B fusion/build-linux -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build fusion/build-linux --target GenerateSohOtr --parallel
python3 -c 'import sys, zipfile; required={"textures/wind-waker/clouds/cloud_mae", "textures/wind-waker/clouds/cloud_naka", "textures/wind-waker/clouds/cloudtx_01", "textures/wind-waker/clouds/cloudtx_02", "textures/wind-waker/clouds/cloudtx_03"}; archive=set(zipfile.ZipFile("fusion/soh/soh.o2r").namelist()); missing=sorted(required-archive); print("Missing Sky assets: " + ", ".join(missing)) if missing else print("Verified all Sky cloud assets in Fusion soh.o2r"); sys.exit(bool(missing))'
python3 fusion/tools/ci/verify_nei_equipment_icons.py fusion/soh/soh.o2r
cp fusion/soh/soh.o2r fusion/Android/app/src/main/assets/soh.o2r
cd fusion
tools/ci/inject_android_renderer_shaders.sh
Expand Down
2 changes: 1 addition & 1 deletion Android/app/src/main/java/com/dishii/soh/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public class MainActivity extends SDLActivity{
private static final int TOUCH_FACE_BUTTON_LAYOUT_GAMECUBE = 2;
private static final String SUPPORT_FILES_VERSION_MARKER = ".android_support_files_version";
// Bump this only when bundled Android support assets or archive layout changes.
private static final String SUPPORT_FILES_VERSION = "sohfusion-android-support-4";
private static final String SUPPORT_FILES_VERSION = "sohfusion-android-support-5";
private AlertDialog dataRootMigrationDialog;
private AlertDialog setupProgressDialog;

Expand Down
16 changes: 12 additions & 4 deletions soh/mods/extended_equipment.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,19 @@ void* ExtEquip_GetIcon(s16 equipType, u8 index) {

const char* path = sExtEquipIconPaths[equipType][index - 1];

// Return the managed resource name, matching the item-page icon path. The
// renderer resolves the texture's real dimensions and scales it into the
// equipment page's existing 32x32 quad, preserving the 128x128 source.
// Return the managed resource name only after confirming it resolves. This
// preserves the source texture metadata used by the renderer while keeping
// an outdated or incomplete support archive from producing an empty slot.
if (path != NULL) {
return (void*)path;
if (strstr(path, "textures/icon_item_custom/") != NULL) {
if (ResourceMgr_FileExists(path)) {
return (void*)path;
}
} else if (ResourceMgr_GetResourceDataByNameHandlingMQ(path) != NULL) {
// MM resources can be mounted after the extension cache is built,
// so resolve them directly before returning the managed path.
return (void*)path;
}
}

// These buffers have static lifetime and are always valid 32x32 RGBA32
Expand Down
52 changes: 52 additions & 0 deletions tools/ci/verify_nei_equipment_icons.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python3
"""Fail an Android build if its generated support archive omits equipment icons."""

import sys
import zipfile
from pathlib import Path


REQUIRED_ICONS = (
"textures/icon_item_custom/gItemIconCaneOfByrnaTex",
"textures/icon_item_custom/gItemIconFourSwordTex",
"textures/icon_item_custom/gItemIconDrillshaftTex",
"textures/icon_item_custom/gItemIconDivineShieldTex",
"textures/icon_item_custom/gItemIconGerudoScimitarTex",
"textures/icon_item_custom/gItemIconMagicCapeTex",
"textures/icon_item_custom/gItemIconPending4Tex",
"textures/icon_item_custom/gItemIconChampionsTunicTex",
"textures/icon_item_custom/gItemIconPegasusAnkletTex",
"textures/icon_item_custom/gItemIconWaterDragonScaleTex",
)


def main() -> int:
if len(sys.argv) != 2:
print(f"usage: {Path(sys.argv[0]).name} <soh.o2r>", file=sys.stderr)
return 2

archive_path = Path(sys.argv[1])
if not archive_path.is_file():
print(f"missing support archive: {archive_path}", file=sys.stderr)
return 1

try:
with zipfile.ZipFile(archive_path) as archive:
entries = {name.removeprefix("__OTR__") for name in archive.namelist()}
except zipfile.BadZipFile:
print(f"invalid support archive: {archive_path}", file=sys.stderr)
return 1

missing = [icon for icon in REQUIRED_ICONS if icon not in entries]
if missing:
print("generated support archive is missing equipment icons:", file=sys.stderr)
for icon in missing:
print(f" {icon}", file=sys.stderr)
return 1

print(f"verified {len(REQUIRED_ICONS)} equipment icons in {archive_path}")
return 0


if __name__ == "__main__":
raise SystemExit(main())
Loading