Majora's Mask vía 2 Ship 2 Harkinian 5.0.1, nativo en iPhone y iPad.
Fork de MaskPad de chrissotraidis,
actualizado a la última versión de upstream y con ProMotion de verdad.
MaskPad es un trabajo excelente de chrissotraidis: lleva 2 Ship 2 Harkinian a iOS con render en Metal y controles táctiles personalizables. Hice este fork porque quería:
- Jugar la última versión de 2 Ship 2 Harkinian. El original estaba en 4.0.2 "Keiichi Charlie".
- Que ProMotion funcione bien. Subir los FPS sobre 60 provocaba caídas bajo 20 FPS en iPhone.
- Aprovechar la resolución real de la pantalla. El juego y los menús se dibujaban a un tercio de la resolución del panel.
- Jugar en la tele. Conectar el iPhone o iPad a una pantalla externa y usar el dispositivo como control.
- Menús más cómodos en pantalla táctil.
Tiene un hermano: HarkinianPad (Ocarina of Time), con el que comparte la libultraship para iOS.
| MaskPad 0.2.1 (original) | Este fork 0.5.3 | |
|---|---|---|
| Upstream | 2 Ship 2 Harkinian 4.0.2 "Keiichi Charlie" | 2 Ship 2 Harkinian 5.0.1 "Battler Bravo" |
| FPS / ProMotion | Interpolaba a 120 pero iOS presentaba a 60 | Interpola a la tasa real de la pantalla: 120 Hz con ProMotion, 60 Hz en modo de bajo consumo |
| Resolución | Juego y menús a 1/3 del panel | Menús siempre nítidos. Opción Native Screen Resolution para el juego |
| Tope de FPS | — | Lock at 60 FPS, opcional, para jugar a resolución nativa con 60 estables |
| Menús táctiles | Sin scroll con el dedo. La barra de categorías tapaba los textos | Scroll con un dedo e inercia, sin mover sliders por accidente. Tooltips con el dedo quieto. Categorías sin barra encima |
| Aviso de caída de FPS | Saltaba en falso con Match Refresh Rate | Compara con el objetivo real de FPS |
| Pantalla externa | Solo duplicaba la pantalla | Extend to External Display: el juego a pantalla completa en la tele o el monitor (USB-C/HDMI o AirPlay) y el dispositivo como control |
| Controles táctiles | Escribían teclas del teclado y el stick era digital. Se ocultaban a mano | Actúan directo como el control del jugador 1, con mapeo fijo y stick análogo. Touch Camera Stick opcional para Free Look y vibración al presionar. Se ocultan solos al conectar un control (queda el botón de menú) |
| Controles de juego en iPadOS 26+ | El control también escribía teclas (flechas, Return, Escape) | Corregido: el control solo actúa como control |
| Metal | — | Caché de estados de depth-stencil |
| Bundle ID | com.chrissotraidis.maskpad |
cl.mtbolanoss.maskpad |
En Settings → Graphics:
- Native Screen Resolution (apagada por defecto). Dibuja el juego a la resolución física de la pantalla. Se ve mucho más nítido, pero exige bastante más a la GPU, la batería y la temperatura.
- Lock at 60 FPS, justo debajo. Solo actúa con la resolución nativa encendida: fija la interpolación en 60 y bloquea el slider de FPS, que conserva tu valor. Si apagas la resolución nativa, la opción queda en pausa con su marca y vuelve a aplicarse al encenderla.
En Settings → Controls:
- Los botones táctiles actúan directo sobre el control del jugador 1, con un mapeo fijo: A es siempre A, C-Up es siempre C-Up, sin importar los bindings. El teclado queda libre, y el stick táctil es análogo (con una zona muerta pequeña).
- Touch Camera Stick (apagado por defecto) agrega un segundo stick que actúa como el stick derecho, para Free Look (hay que activar Free Look). Se mueve y cambia de tamaño en Customize Touch Layout.
- Touch Haptics (encendido por defecto): vibración suave al presionar un botón táctil.
Con Extend to External Display activado (viene así por defecto, en Settings → Graphics), al conectar una tele o un monitor:
- El juego pasa a pantalla completa en la pantalla externa, a su resolución real de salida. Si pesa demasiado, baja Internal Resolution.
- El dispositivo muestra un ícono de tele y, encima, los controles táctiles, o solo el botón de menú si hay un control conectado.
- El menú abierto con el botón
•••aparece en el dispositivo mientras está abierto. Abierto desde un control, aparece en la pantalla externa. - Native Screen Resolution y Lock at 60 FPS no aplican mientras haya una pantalla externa: se ven oscurecidos y conservan su valor.
- Con la opción apagada, la pantalla se duplica como siempre.
- Arrastrar hace scroll, con inercia, y nunca presiona botones ni mueve sliders.
- Solo un arrastre claramente horizontal mueve un slider.
- Con el dedo quieto se muestra el tooltip sin presionar nada. Un toque se aplica al soltar.
- Las barras de scroll laterales se agarran y arrastran como en un navegador.
- Los controles táctiles del juego no pasan por este filtro.
El historial de versiones está en CHANGELOG.md.
Este repositorio no publica apps compiladas. Cada quien compila la suya desde el código de 2 Ship 2 Harkinian (ver derechos y licencias).
Necesitas un Mac con Apple Silicon y Xcode, además de las dependencias de compilación:
brew install cmake ninja pkgconf sdl2 glew nlohmann-json libpng libzip \
tinyxml2 libogg libvorbis opus opusfile sdl2_net
git clone https://github.com/Mtbolanos/maskpad.git
cd maskpad
scripts/clone-sources.sh
scripts/apply-patches.sh
scripts/configure-ios.sh --device
scripts/build-ios.sh --device
scripts/package-unsigned-ipa.shEl resultado es artifacts/MaskPad-0.5.3-unsigned.ipa. Fírmalo con tu
herramienta de sideloading de siempre. Cada push también compila en GitHub
Actions. Para el simulador, la firma con tu propio equipo de desarrollo y el
detalle completo, ver docs/building.md (en inglés).
Note
¿Vienes del MaskPad original? Este fork usa otro bundle ID, así que se
instala como una app aparte. Para llevarte tus partidas, copia Save/ y tus
mods desde la carpeta del original. No copies mm.o2r (se regenera desde
tu ROM). Es mejor no copiar la configuración antigua, porque viene de 4.0.2.
- Abre la app una vez para que iOS cree su carpeta.
- En Archivos → En mi iPhone → MaskPad, copia tu ROM de Majora's Mask
(
.z64,.n64o.v64). - Vuelve a la app y toca Rescan. Déjala abierta mientras genera
mm.o2r. - A jugar.
La ROM y el archivo generado nunca salen de la app.
Los controles táctiles son los del original: stick, D-pad, A/B/Z, botones C alineados con el HUD del juego, L/R y Start, con un editor para mover, cambiar de tamaño u ocultar cada uno, y opacidad ajustable. Desde Settings → Controls puedes ocultarlos cuando usas un control físico. También hay soporte para teclado, mouse/trackpad y controles compatibles con SDL2. Para apuntar con el giroscopio de un control, activa su sensor en Settings → Controls → Gyro y luego Enhancements → Camera → First Person → Gyro Aiming.
flowchart LR
A["2 Ship 2 Harkinian 5.0.1<br>(upstream oficial)"] --> C["Parches iOS<br>patches/"]
B["libultraship · ZAPDTR<br>(submódulos de 5.0.1)"] --> C
C --> D["Overlays iOS<br>ios/ · port/"]
D --> E["IPA sin firmar<br>(sin ROM)"]
F["Tu ROM"] --> G["Extracción<br>en el dispositivo"]
E --> G
G --> H["mm.o2r + juego"]
| Ruta | Para qué sirve |
|---|---|
patches/2ship-ios.patch |
Integración iOS sobre 2 Ship 2 Harkinian |
patches/libultraship-ios.patch |
libultraship para iOS, compartida con HarkinianPad |
patches/zapdtr-ios.patch |
Extractor de assets para iOS |
ios/, port/ |
Código iOS (controles táctiles, ciclo de vida) y CMake |
scripts/ |
Clonar, parchar, compilar y empaquetar |
- chrissotraidis, autor de MaskPad: la integración iOS, los controles táctiles y todo lo que hace posible este fork.
- Harbour Masters, por 2 Ship 2 Harkinian, libultraship, ZAPDTR y OTRExporter.
- El proyecto de decompilación de Majora's Mask, SDL y sus contribuidores.
Proyecto comunitario no oficial, sin relación con Nintendo ni con Harbour Masters. No incluye el juego, ROMs ni datos derivados de una ROM: necesitas tu propia copia legal.
El código propio de MaskPad pertenece a chrissotraidis y no tiene una licencia
libre. Lee RIGHTS_AND_LICENSES.md (en inglés) antes de
copiar o distribuir. Cada componente de terceros conserva su propia licencia.
