Superman Returns Recomp
Superman Returns Recomp is a native PC port of Superman Returns for Windows that allows playing the game with Direct3D 12 or Vulkan.
- Type: PC port
- Game: Superman Returns
- Runs on Windows
- By MrPowerUp82
- Latest release v2026.10.30-88c81bc, 2026-10-31
- Source: https://github.com/MrPowerUp82/superman_returns_recomp
- Website: https://mrpowerup82.github.io/superman_returns_recomp/
README
Superman Returns Recomp
Projeto experimental de recompilação estática da versão Xbox 360 de Superman Returns para PC com ReXGlue v0.10.0. O código-fonte C++ é gerado localmente a partir do default.xex fornecido pelo usuário. O renderer nativo já chega à gameplay (ainda sem validação completa de imagem e de todas as fases), então o projeto está em estágio experimental, não finalizado.
Versão analisada
- Xbox 360 Title ID:
454107ED; Media ID:64A4002A; versão do XEX:0.0.0.1. - SHA-256 de
default.xex:C8F243ACD99DE9A91F5AE4F409721C0E954E3D5EB96861419D3DA07B8106DB2B. - A ISO contém
default.xexe 12 arquivos.ASTemDATA/. Os arquivos do jogo ficam emgame/, ignorados pelo Git.
Estado atual
O objetivo do projeto é um renderizador nativo próprio (sr_renderer=native, o padrão), com dois backends: Direct3D 12 e Vulkan (--sr_native_api=d3d12|vulkan). Ele intercepta as chamadas Direct3D do XDK e desenha direto na GPU do PC, sem emular a GPU Xenos do Xbox 360. O jogo compila, chega à gameplay com áudio, e o renderer nativo desenha a cidade, o Superman, o HUD e o minimapa. A imagem ainda não está validada em todas as fases, então o projeto continua experimental.
O backend Xenos (a emulação da GPU herdada do Xenia, plugin xenos) continua disponível só como compatibilidade, quando escolhido explicitamente (--sr_renderer=xenos ou "Xenos (compatibilidade)" no launcher). Opções desse backend, como render_target_path_d3d12 (RTV/ROV), não afetam o renderer nativo.
Marcos recentes:
- 2026-10-05: backend Vulkan; correção da queda silenciosa para o Xenos quando o launcher mandava uma GPU em branco (o nativo nunca mais troca de backend sozinho).
- 2026-10-27/28: limite interno de 30 Hz removido do padrão, correção da música que parava após a decolagem (último bloco do XMA), otimizações de CPU no D3D12 nativo, benchmark embutido e binds de
Shift/Ctrl/Altsozinhos no teclado. - 2026-10-29: trajes (Golden Age sem desbloquear e a skin Reino do Amanhã) e dump e troca de texturas.
Histórico e validações: gameplay nativa, Vulkan, pistas de desempenho de 28/10.
Correções específicas do jogo
- Travamento do áudio / crash após 1–2 min em cenas 3D (
port/src/xma_fixes.cpp): o mixer de áudio fica em espera ativa pelo decodificador XMA sem timeout. Sob a emulação de XMA do runtime alguns contextos nunca entregam amostras (contexto já liberado, ou buffer de saída marcado cheio), a thread de áudio travava, a fila de comandos de 1 MB (sub_8264C540) parava de ser esvaziada e transbordava sobre o heap. Um hook midasm em0x826595B8reativa o contexto e, se ele estiver liberado, se o kick não mudar nada (sem entrada ou buffer de saída cheio) ou se não entregar em 1 ms, faz o mixer seguir para o próximo stream. - Som engasgando quando o Jor-El começa a falar (mesmo hook): o
XMAEnableContextdo runtime decodifica na hora, então um contexto sem dados de entrada (a voz do Jor-El vem em stream do disco) não vai entregar nada enquanto o mixer espera. A versão anterior do hook esperava até 4 ms por stream em todo passe do mixer; com a voz dividida em vários contextos isso passava de um quadro de áudio (5,3 ms), o mixer ficava atrás do tempo real e só o som engasgava. Agora o hook desiste assim que um kick não faz progresso.
As dicas de limites de função estão em port/superman_returns_manifest.toml. A maior parte foi encontrada por tools/analysis/find_missing_funcs.py, que procura thunks de vtable e funções pequenas que a análise estática do ReXGlue não descobre. O código gerado não tem nenhum REX_FATAL.
Instalar sem compilar
Quem não quer compilar pode usar a página do instalador (GitHub Pages deste repositório): ela lê o seu ISO ou a sua pasta do jogo no navegador, confere o default.xex, baixa o build pré-compilado e grava tudo em uma pasta ou em um .zip. O pacote não contém dados do jogo nem shaders traduzidos: os shaders são traduzidos no seu PC na primeira execução e ficam em cache. Detalhes, limites e como gerar e publicar um build em docs/installer.md.
Como jogar
O launcher com GUI permite escolher a API gráfica (Direct3D 12, o padrão recomendado, ou Vulkan, experimental), GPU, resolução, controles e opções gráficas antes
de iniciar. Preferências já salvas mantêm a API escolhida. Com Vulkan, escala interna, FXAA, MSAA, sombras e filtro anisotrópico ficam no padrão do jogo; essas opções só valem em Direct3D 12. Compile o launcher com powershell -File tools/build_launcher.ps1 e abra
artifacts/launcher/SupermanReturnsLauncher.exe. A versão portátil inclui .NET;
detalhes em launcher/README.md. O pacote de distribuição também
inclui o launcher. A seleção de GPU exige o executável do jogo da mesma build.
Depois de compilar com build.cmd:
| Script | Uso |
|---|---|
run.cmd | Controle de Xbox (ou compatível com XInput/SDL). Conecte-o antes de abrir o jogo. |
run_keyboard.cmd | Teclado e mouse. O runtime emula um controle de Xbox 360 e o mouse move a câmera. |
Os dois aceitam opções extras, por exemplo run.cmd --fullscreen. O log fica em logs/game.log. Para escolher a API fora do launcher, use --sr_native_api=d3d12 ou --sr_native_api=vulkan (o padrão do executável continua d3d12).
Benchmark
O botão BENCHMARK do launcher abre o jogo direto no sobrevoo da cidade da tela de título, sem logo nem menu, com as configurações escolhidas. Depois de 5 s de aquecimento, ele mede 60 s e mostra FPS médio, mínimo, 1% e 0,1% low, tempos de quadro e as configurações usadas. Esc ou Enter fecham o jogo. O resultado também é salvo em benchmarks\benchmark-AAAAMMDD-HHMMSS.json, com o tempo de cada quadro num .csv. Teclado e controle ficam desligados durante a rodada.
- Por linha de comando:
run.cmd --sr_benchmark=true. Com--sr_benchmark_exit=true, o jogo fecha sozinho depois de salvar, com código de saída 0 se a rodada for válida e 1 se não for. - Sem janela na tela (para scripts):
--sr_benchmark_headless=true. A janela vai para fora da tela assim que o jogo começa a apresentar quadros, o foco do teclado volta para a janela que abriu o jogo, e ao fim o jogo fecha sozinho (como--sr_benchmark_exit) e escreve uma linha de resumo no stdout (redirecione a saída para lê-la). O jogo continua renderizando normalmente na GPU: ocultar ou minimizar a janela pararia a apresentação, por isso ela só é movida. - A rodada é marcada como inválida se a cena 3D parar ou se o vídeo de demonstração do título começar (~77 s depois da cena).
- O voo não é idêntico a cada abertura: no mesmo PC, a média variou ±4,5% entre rodadas. Para comparar builds, use a média de três rodadas.
- Medido em 28/10 num i5-13420H + Intel UHD, 1280x720, sem limite: Direct3D 12 com 55,1 / 57,9 / 53,0 FPS e Vulkan com 41,6 FPS.
Detalhes no design do benchmark.
Trajes
O campo Traje do launcher escolhe a roupa do Superman sem desbloquear nada e sem gravar no save:
| Opção | Linha de comando | O que faz |
|---|---|---|
| Padrão do jogo | (nada) | O traje que o jogo escolher. |
| Golden Age | --sr_costume=2 | Veste o Golden Age Superman, mesmo bloqueado. |
| Reino do Amanhã | --sr_costume_skin=kingdom_come | Repinta o traje do filme como o Superman do Reino do Amanhã da CW: escudo vermelho com o S recortado em preto, sunga e botas vermelhas, cinto preto com fivela oval dourada. |
- O Reino do Amanhã é uma receita no código que repinta, durante o jogo, as texturas do traje lidas do seu disco. Nenhuma imagem do jogo vem com o projeto.
- A skin aparece quando o Superman está com o traje do filme. Com outro traje vestido no menu do jogo, o log avisa.
--sr_costumetambém aceita1(Pod Suit), que ainda não foi testado. O jogo volta ao traje do filme quando recria o Superman em cinemáticas e cargas de fase, e o traje escolhido é vestido de novo nessas horas.
Texturas (dump e troca)
Funciona nos dois backends nativos (Direct3D 12 e Vulkan):
--sr_texture_dump_dir=<pasta>grava cada textura 2D distinta uma vez, como<chave>.png, e uma linha por textura emindex.csv(key,width,height,format). A chave é um hash do conteúdo e do formato, a mesma em toda execução e nos dois backends.- PNGs com o nome
<chave>.pngna pastatextures\ao lado do executável (ou em--sr_texture_replace_dir=<pasta>) substituem a textura original. O PNG precisa ter o mesmo tamanho da original; senão, o log avisa e a original fica. Um PNG vence a skin para a mesma chave. --sr_texture_replace=falsedesliga as trocas e as skins.- O mapa das texturas do Superman está em docs/kingdom-come-texture-map-2026-10-28.md.
tools/texture_mods/find_costume_textures.py <dump A> <dump B>lista as texturas que só aparecem no segundo dump.sr_skin_preview <dump> <saída>(emtests/native) aplica a skin aos PNGs de um dump, para ver a arte sem abrir o jogo.
Desempenho
O limite nativo de 30 FPS foi retirado do padrão: o executável e novas preferências
do launcher usam sr_native_fps_limit=0. É possível selecionar 30, 60 ou 120 no
launcher ou passar --sr_native_fps_limit=60. O modo sem limite agora usa o
mecanismo do Xenia Canary: sr_native_fps_limit=0, VSync desligado e vblank
seguido de espera de 1 ms. Esse é o padrão nativo para opções não definidas;
opções explícitas prevalecem. Com limite zero e VSync ligado, a cadência de
vblank fica em 60 Hz. O port também faz o contador de varredura avançar.
Um segundo gate, interno ao scheduler de renderização do jogo, também segue
o alvo de FPS: limite zero usa um piso de 1 ms; 30 mantém o comportamento
original. O peer de simulação permanece com seu tick original. Para comparar
com o gate interno de 30 Hz, use --sr_native_guest_render_scheduler=false.
O desempenho medido na cidade ainda não comprova 60 FPS. Detalhes e limites em
desbloqueio do Xenia Canary.
O build.cmd agora inclui por padrão o runtime verificado com rastreamento de
escritas, necessário para evitar hashes de texturas com conteúdo comprovadamente
inalterado. O D3D12 já usa staging em CPU, leituras limitadas de constantes e
cache de resolves por identidade completa. Sem cobertura segura, a validação
por hash continua. set SR_MEMORY_TRACKING_SDK=OFF permite compilar com o runtime
original. Detalhes e validação em
CPU e desbloqueio de FPS.
Em 29/10, o D3D12 passou a verificar texturas intactas pelas épocas das páginas sem consultar os locks do runtime quando a prova do upload continua válida. Também foram corrigidos o tamanho do pacote em bits e o argumento do segundo kick no flush XMA. Build, testes e limites da comparação de desempenho estão no relatório das otimizações das referências.
O renderer também evita preparar slots de textura não usados pelos shaders,
com fallback completo para shaders desconhecidos. A opção
--sr_native_used_texture_mask=false restaura o caminho anterior após reiniciar.
Testes e medições em máscara de texturas usadas.
Texturas que diferem apenas em filtros, clamp ou LOD bias também compartilham
armazenamento no D3D12, preservando seus samplers e versões de conteúdo.
No Vulkan, esse compartilhamento é experimental e fica desligado por padrão
após regressão nos ensaios desta máquina. SR_NATIVE_TEXTURE_STORAGE_REUSE=0
desliga nas duas APIs; =1 força nas duas. Defina a variável antes de iniciar.
Testes e limites em compartilhamento de texturas.
O reaproveitamento de bancos por constantes usadas pelo shader está
experimental e desligado por padrão: eliminou escritas, mas piorou os dois
pares D3D12 medidos. Pode ser testado com SR_NATIVE_USED_CONSTANT_MASK=1;
no Vulkan portável depende também de SR_VULKAN_CONSTANT_BANK_CACHE=1.
Validação e medições.
O runtime do build padrão também drena o PCM XMA já decodificado quando a entrada acaba, respeitando espaço/padding e retornando se não houver progresso. Correção e testes de drenagem XMA.
A última etapa, atualizações seletivas de texturas, está implementada nas duas
APIs e é experimental (SR_NATIVE_TEXTURE_UPDATES=1, padrão desligado).
Ela reaproveita recursos compatíveis após concluir seu uso e preserva versões
pendentes; o decode continua completo. Implementação e testes.
No Windows, o monitor de memória agrupa consultas e proteção por regiões,
preservando os limites observados e os direitos de cada alias. Esse caminho
fica ligado por padrão; SR_TRACKING_BATCH_ARM=0 restaura o legado após
reiniciar. Nos ensaios, o ganho mais claro foi remover pausas longas em Compare;
o FPS normal variou entre pares. Pesquisa e benchmarks de CPU.
Para repetir A/B sequencial sem instrumentação: python tools/bench/cpu_web_sweep.py --suite arm --blocks 3 --cpu-profile 0.
DLSS Quality funciona no renderer nativo D3D12, com SDK oficial instalado e
GPU RTX compatível. O build detecta o SDK local; SR_DLSS=OFF permite desabilitar
o suporte. Ative NVIDIA DLSS no menu ou use --sr_dlss=quality. Há movimento
apenas de câmera, portanto objetos em movimento ainda podem deixar rastros.
Correção e validação na RTX 2060.
No renderer nativo, num i5-13420H + Intel UHD, o quadro é limitado pela GPU integrada: a cena principal ocupa ~72% do tempo de GPU. O trabalho de CPU do worker D3D12 fica em ~13 ms por quadro. Números atuais na seção Benchmark; análise em pistas de desempenho de 28/10.
As medições abaixo são históricas e registram explicitamente os limites usados. Medido no fechamento do ciclo 3 em 2026-10-06 no mesmo i5-13420H + Intel UHD, com tools\bench\bench_api.ps1 (New Game, 20 s parado e 20 s andando, janela 1280x720, limite de 30 FPS; o script só mede depois de ver o HUD do jogo na tela):
| Renderer | Parado | Andando | Observação |
|---|---|---|---|
native, Direct3D 12 | 25,5 FPS | 27,5 FPS | execução final; GPU a 72–77%; resultados históricos ~30 FPS variam com a cena |
native, Vulkan (ciclo 3, 2026-10-06) | 17,4 / 17,6 FPS | 18,4 / 17,5 FPS | duas execuções seguidas; gates de imagem PASS; gravação ~28–32 ms; meta ≥ 29 FPS não atingida |
O ciclo 3 reduziu o custo da gravação Vulkan de ~50–56 ms para ~28–32 ms, mantendo texturas exatas por quadro e posse dos recursos até o fence. O FPS ainda depende do worker de replay, da captura na thread do jogo e da GPU. No fechamento, o D3D12 mediu 25,5 FPS parado e 27,5 andando; a câmera variável impede concluir ausência de regressão com uma única execução. Resultados por tarefa e limitações dos testes estão no spec do ciclo 3. Novas otimizações exigem uma decisão de escopo.
Backend Xenos (compatibilidade)
O backend xenos emula a GPU do Xbox 360 e só roda quando você o escolhe. Ele não é o foco do projeto e é bem mais pesado que o nativo: numa GPU integrada fica a ~98% nas cenas 3D. As opções abaixo valem só para ele. Medições num i5-13420H com Intel UHD:
Modo de render (--render_target_path_d3d12) | Vídeos de abertura | Cena 3D (tela de título) |
|---|---|---|
rov (padrão do runtime) | 30 FPS | ~2 FPS |
rtv (padrão deste projeto) | ~16 FPS | ~10 FPS |
Neste hardware o RTV ficou bem à frente, então o jogo aplica por padrão, em port/src/superman_returns_app.h: render_target_path_d3d12=rtv, depth_float24_convert_in_pixel_shader=true (sem ela o céu e o fundo ficam pretos no rtv) e native_stencil_value_output_d3d12_intel=true (dica do Xenia para GPUs Intel, xenia-canary#542: 7,6 → 10,2 FPS na rua). Em outras GPUs o ROV pode se sair melhor: qualquer opção passada na linha de comando prevalece, por exemplo run.cmd --sr_renderer=xenos --render_target_path_d3d12=rov.
Se o D3D12 nativo ficar em 9–11 FPS com a GPU a 100%, o jogo provavelmente está no backend Xenos: confira o log (veja Solução de problemas).
Para medir, F3 abre um painel com o FPS do jogo, e set SR_LOG_FPS=1 antes de rodar grava o FPS em logs/game.log a cada 2 s. F4 abre as configurações do runtime.
Presets (sr_preset)
--sr_preset=quality (padrão) mantém o visual atual; --sr_preset=performance hoje não muda nada (o sr_post_effects=false foi retirado do preset após a validação abaixo); --sr_preset=custom não altera nenhuma opção. O preset só preenche opções que continuam no padrão: uma opção passada na linha de comando, no ambiente ou no .toml prevalece. sr_render_scale ainda é experimental e nenhum preset o altera. Detalhes e limitações em docs/performance-design.md.
Pós-processamento (sr_post_effects, experimental, não validado)
--sr_post_effects=false (padrão true, exige reiniciar) desliga a cadeia de bloom/raios de luz. Exige o backend D3D12 em processo (tools/setup_gpu_source.ps1 antes do build.cmd); sem ele a opção é ignorada com aviso no log. Com a opção desligada, o processador de comandos do projeto pula os quads (primitiva 13 = quad list) das superfícies menores que a cena (640, 320, 160 e 80 pixels de largura) e o resolve que segue cada um. Os passes na superfície de 1280 (entre eles a composição final) e o HUD continuam. A lista fica em port/src/native_renderer/post_effects.h e foi derivada do trace docs/data/gpu_groups_gameplay_intel_uhd.csv. Validado em 2026-09-29 (i5-13420H + Intel UHD, post_effects_check.ps1, 2 pares): nenhum ganho de FPS (−1% parado, −6% andando, dentro do ruído) e imagem corrompida com a opção desligada (ruído na tela: os resolves pulados deixam lixo nas texturas que a composição final lê). Não use false até a opção ser refeita. O teste anterior que pulou todos os draws de primitiva 13 (inclusive os de 1280 e o HUD) deu 8,4 FPS contra 7,1, com imagem não verificada; não é uma estimativa desta opção.
Para validar em casa: powershell -File tools\bench\post_effects_check.ps1 -Pairs 2 -Trace. O script roda o tools\bench\bench.ps1 com a opção ligada e desligada, compara os screenshots (logs\post_effects_<nome>_*_diff.png), confere no log quantos passes foram pulados e, com -Trace, lista a ordem dos passes de um quadro com tools\bench\post_effects_trace.py. Se a imagem quebrar (tela preta, brilho congelado ou lixo), o relatório do trace indica quais passes mantidos leem as texturas que deixaram de ser atualizadas.
Desenvolvimento do renderizador próprio
O modo experimental --sr_renderer=trace já usa um processador de comandos do projeto. Ele registra draws, cópias, swaps, hashes de shaders e estados gráficos, mas ainda delega a renderização ao backend Xenos D3D12. É uma ferramenta de migração, sem ganho de FPS esperado. O modo padrão é native (veja abaixo).
Para compilar o modo de captura, execute powershell -File tools\setup_gpu_source.ps1 antes de build.cmd. O script baixa somente o código gráfico do ReXGlue v0.10.0 para .tools/. Para capturar 120 quadros de gameplay após o início de um jogo novo, execute `powershell -File tools\analysis\