Super Mario All-Stars

Windows PC & Android port of Super Mario All-Stars with true widescreen up to 21:9, simultaneous two-player co-op, 82 achievements, CRT filters and slang shaders, save states, rewind, cheats, level select and music player.

README

Super Mario All-Stars — PC Port

A native Windows and Android version of Super Mario All-Stars (SNES) with a launcher, true widescreen, re-anchored HUDs, display options, cheats, level select, achievements, a sound test and a music player. It contains no game data: it runs from your own ROM (Super Mario All-Stars (USA).sfc, CRC32 925637C7); no game starts without it.

Building

Requirements: Windows 10/11, Visual Studio 2022 (C++ workload) and CMake 3.20+. No other libraries are needed (Direct3D 11, Direct2D, XAudio2, XInput and DirectInput come with Windows).

build.bat

The program is written to build\Release\SuperMarioAllStars.exe.

Android

The same code builds for Android (android/), as the Mickey & Donald Collection's does: SDL2 2.32.10 compiled from source for the window, sound and controllers, OpenGL ES 3.0 for the picture. You need the Android SDK with NDK 28.2 and CMake 3.31.6 (both from the SDK manager) and JDK 17 or later. The SDL2 source belongs in third_party/SDL2-2.32.10-src (android/fetch_sdl.ps1 downloads and checks it), then:

cd android
gradlew assembleDebug

The APK ends up in android/app/build/outputs/apk/debug/ (64-bit ARM phones and tablets, Android 6.0 or later, and the x86_64 emulator). Release builds are signed when android/keystore.properties names a keystore (storeFile, storePassword, keyAlias, keyPassword), as the Disney collection's are.

Running

Put the ROM next to the executable, in a roms folder beside it, or in any parent folder up to three levels up; the location is remembered in rompath.txt. Without it the launcher's cards say ROM not found and what is needed, and a ROM copied in while the launcher is open is picked up within a second. Another version or dump of All-Stars runs too, its file name shown in amber on the cards: widescreen, cheats and the level select are tuned for the USA version.

To start a game directly, give SuperMarioAllStars.exe the argument --game smb1, --game smbll, --game smb2 or --game smb3 (for example in a shortcut).

Battery saves go to saves\smas.srm, save states to saves\, screenshots to screenshots\, settings to smas_port.ini. Files are written in full before they replace the old ones, so a full disk can't leave a truncated save (you are told the save failed instead). Save states carry a checksum: a damaged one is refused rather than loaded. They also keep the widescreen state, so a state loads exactly as it was saved, and one saved at a narrower width (or by an older version) brings in the enemies of the wider view. If the graphics driver resets (a driver update or crash), the picture comes back by itself and the game keeps running.

On Android

Install the APK (Android asks you to allow installing apps from the place you opened it). On the first start the launcher's card says ROM not found: tap it, pick Super Mario All-Stars (USA).sfc (or a .smc) in the file picker, and it is copied into the app. A ROM can also be put in the app's folder Android/data/com.darhkfox.allstars/files (or a roms folder there) with a computer.

  • Touch: an SNES pad over the game: the D-pad bottom left, A B X Y bottom right, L and R at the sides, Select and Start bottom centre, Menu top left, and (when they're switched on and achievements are off) rewind and fast forward top right. Tap a game's card to choose it, tap it again to play; in the menus tap a row to use it, drag to scroll, and the button top right goes back.
  • Controllers and keyboards work as on Windows (the same bindings); the on-screen controls hide while one is in use (Options → Controls → On-Screen Controls: While Touching, Always or Never, and their opacity).
  • Back opens and closes the menu, as Esc does.
  • The picture fills the screen (Aspect Ratio: Auto), with the same filters and colour settings. The window settings, VSync, Black Frame Insertion, High Frame Rate and slang shaders are Windows only.
  • Saves, states and settings are kept in the app's own storage; screenshots go to Android/data/com.darhkfox.allstars/files/screenshots. Leaving the app saves the game's progress.

Launcher

The program opens on a launcher, laid out like the Mickey & Donald Collection's, over a night-blue sky with twinkling stars and a checkerboard floor after the All-Stars title screen. By default it shows one Super Mario All-Stars card with a live preview of the cartridge's title: choosing it starts the cartridge as it is, at its own title and game select (--game allstars starts it directly). Below are buttons for Options, Achievements, Music Player, Credits and Quit.

Options → Launcher Shows → The Four Games gives one card per game instead (Super Mario Bros., The Lost Levels, Super Mario Bros. 2, Super Mario Bros. 3), each with a live attract-mode preview of that game and the chosen card's sound playing. Each preview is its own console run through the All-Stars game select into the game's title, out of sight while it starts. Choosing a card resets the console and takes it through the All-Stars menu to that game's save files (behind a short black loading screen), where you pick the file as usual. The launcher remembers the last game chosen.

Options → Game Covers shows the player's own cover pictures on the cards instead of the live previews, and Custom Background their own picture behind the launcher (filling the window, darkened a little so the text reads). None are shipped. PNG or JPG files named smb1, lostlevels, smb2, smb3, allstars (the single card) and background go in the covers folder (Open Covers Folder: next to the exe on Windows, in ~/.local/share/SuperMarioAllStars on Linux); on Android Choose Cover / Choose Background copy a picture from the phone in. They're read with stb_image (third_party/stb, public domain / MIT), big ones shrunk to 1024 px (2048 for the background). A card without a cover keeps its preview; one with a cover runs no preview console at all, which also makes the launcher lighter on slow devices.

Controls

KeyboardJoypad (Xbox layout; PlayStation, Switch Pro and USB/SNES pads supported)
D-padArrow keysD-pad / left stick
B / A / Y / XZ / X / A / Sbottom / right / left / top face buttons
L / RQ / WLB / RB
StartEnterMenu/Start
MenuEsc or Right Shift (Select)View/Select
Game's Select buttonMenu → Press Select In Gameleft stick press
Save / load stateF5 / F8
Fast forwardTab (hold)RT (hold)
RewindBackspace (hold)LT (hold)
FullscreenF11 or Alt+Enter
Launcher: choose / play / quitArrow keys / Enter / EscD-pad / A / B
ScreenshotF12

Hold Rewind to go back through roughly the last minute of play (at twice the game's speed), then let go to carry on from there; game progress the game has saved is never undone. Rewind and fast forward can each be switched off under Menu → Controls.

Everything can be rebound under Menu → Controls (keyboard and pad, both players). Each controller keeps its pad number while others are plugged in or out, and gets it back when it reconnects, so the players never swap controllers. Select opens the menu and backs out of it. The games only need their own Select button for the All-Stars save menu (pause, then Select). If you'd rather have it on Select, set Controls → Select Button to "Tap: Game Select - Hold: Menu". In the menus and the launcher the pad's bottom face button confirms and the right one goes back; Controls → Menu Buttons → Right Confirms swaps them (Nintendo's layout).

Menu

The pause menu is a dark panel over the dimmed game, tinted in the running game's colour (red SMB1, green Lost Levels, purple SMB2, orange SMB3; the launcher's buttons gold). Every row explains itself in the line at the bottom. It is laid out as:

  • Resume and Press Select In Game.
  • Save states — the slot (with the time it was saved, or "Empty"), Save State, Load State.
  • Game — Level Select, Cheats, Achievements (earned / total), Sound Select, Music Player, Options (Display, Graphics, Colour, Audio, Controls, fast forward and rewind, achievements on or off), Credits.
  • System — Take Screenshot, Reset Game (back to the game's save files), Return to Launcher, Quit to Desktop (the last three ask first).

Short notices (state saved, screenshot taken) appear in the top-right corner, or at the bottom while the menu is open. An unlocked achievement shows a banner at the top of the screen.

What each page holds:

  • Level Select — every level listed under its world, the game chosen at the top (it starts on the one being played); picking one asks first. For SMB2 a Character choice (Mario, Luigi, Toad, Peach) sets who plays it, picked for you on the character select. Any world and level of all four games: SMB1, The Lost Levels (worlds 1–9 and A–D), SMB2 (1-1 to 7-2) and SMB3 (every world map, numbered level and fortress, and the levels without a numbered panel: each world's airship and the Coin Ship, World 2's desert and pyramid, World 5's second fortress and tower, World 7's Piranha Plant levels, World 8's tanks, battleship, hand traps, super tanks and Bowser's castle. Those are entered from 1-1's panel with the level swapped as it loads, the map left as it was). The chosen level comes up directly: the game is run to it behind a short black loading screen, launched from the game-select screen when needed (a running game is reset first, so unsaved progress is lost). In SMB3 it is a new game in that world, with the world as play would have left it: the levels numbered before the chosen one are cleared, and where the map's paths lead to it on foot, the fortresses before it too, with their locks open (World 1's 1-5: 1-1 to 1-4, the fortress and its lock). Where the way leads through a map pipe (World 4 on), only the numbered levels are. Clearing the level marks its panel as usual; losing a life there sends Mario back to the world's start, from where the cleared part of the map is open.
  • Cheats (per game) — SMB1/Lost Levels: infinite lives, star power, invincibility, always fire, infinite time, moon jump. SMB2: infinite lives, full health, star power, four hearts, super jump, float like Peach. SMB3: infinite lives, star power, infinite flight, full P-meter, infinite time, always raccoon, stocked item box, invincibility.
  • Sound Select — classic sound test: any music number of any game's sound bank plus the three sound-effect channels.
  • Music Player — named track lists for the menu, SMB1 & Lost Levels, SMB2, SMB3 courses and SMB3 world maps, with repeat / play-next and an 8-channel level display. It plays on its own sound chip, so the game is untouched.
  • Display — windowed / borderless / exclusive fullscreen, monitor selection, window size, aspect ratio (4:3, 16:10, 16:9, 21:9, auto), pixel shape (CRT 8:7 or square), scaling (fit, integer, stretch; integer uses whole multiples both ways, with CRT pixels as close to 8:7 as that allows), HUD re-anchoring, widescreen enemy behaviour, dimmed sides in SMB2's wrap-around climbing areas, side-border style, VSync (turn it off for G-SYNC / FreeSync), black frame insertion (a black refresh after each game frame for sharper motion, like a CRT; needs VSync and a 120, 180 or 240 Hz display, and the picture gets darker), High Frame Rate (on 100 Hz and faster displays the refreshes between the game's 60 frames show in-between pictures: each line is drawn again with the layers' scroll and the sprites part of the way back to the last frame, cuts and jumps left as they are; the game still runs at 60 and the picture is a frame later; at a rate that isn't a multiple of 60, like 100, 144 or 165 Hz, each in-between is drawn at the moment its refresh shows it, so motion stays even; with VSync off, on G-SYNC / FreeSync, they're presented at the display's rate), FPS counter.
  • Graphics — nearest, sharp bilinear, bilinear, CRT scanlines, CRT aperture grille and LCD grid filters, effect strength, screen curvature, sprite-limit removal. Slang Shader runs a RetroArch slang preset (.slangp) in place of the filter, through librashader (librashader.dll next to the exe, MPL-2.0, third_party/librashader; without it the game runs on the built-in filters). Presets are listed from a shaders folder next to the exe, with their shader files beside them, e.g. the libretro slang-shaders collection; the colour settings don't apply to them. Seven CRT presets are bundled (third_party/slang-shaders, copied to shaders\ by the build): crt-lottes (public domain), crt-geom, crt-royale, crt-easymode, crt-aperture, zfast-crt and crt-pi (GPL, LICENSE-GPL-2.0.txt), unmodified from libretro/slang-shaders with only the files they use; see third_party/slang-shaders/README.txt. Some presets assume a 4:3 picture and can stretch or frame oddly in widescreen.
  • Colour — colour profiles (Original, Vivid, CRT Television, Muted, Greyscale, Sepia, Pocket, Virtual, Night, Console Accurate), brightness, contrast, saturation, gamma, colour temperature, colour-vision assist (protanopia / deuteranopia / tritanopia), and Mario's Colours / Luigi's Colours: alternate outfits for each brother (Super Mario Bros. and The Lost Levels), kept by each in co-op whichever is the game's player.
  • Menu Style — how the menus look: Storybook (the default: a cream card with a dark outline, Luckiest Guy titles in the game's colour, a yellow star cursor), Retro (black with brick bars, a 5x7 pixel font drawn by the port, ? block switches), Themed Dark (the dark panel under a heading in the game's pattern: bricks, the Lost Levels' green bricks, SMB2's starry night, SMB3's checkers) or Classic (the original dark panel). src/app/menu.cpp.
  • Audio — volume, Music Volume and Sound Effects Volume (each 0–100%: music off with the sound effects kept, or the other way round; the sound driver marks the voices an effect holds at ARAM $1A, so the rest are the music and only the mix changes), latency, mute when unfocused, and Music Pack: an MSU-1 custom soundtrack (see below).
  • Updates — Check for Updates (on by default): once a day the launcher reads GitHub's public "latest release" for this repository (src/app/updatecheck.cpp; WinHTTP on Windows, the system curl on Linux, HttpURLConnection on Android, from a background thread) and shows a badge when its tag is newer than the app's version; the badge, or Get Version, opens the release page. Nothing is sent but the request; nothing is downloaded or installed.
  • Gameplay — NES Brick Bounce: in Super Mario Bros. and The Lost Levels, a brick broken from below sends Mario back down as on the NES instead of letting him keep rising (BMF54123's brick fix, updated by Blittle McNilsen, written into the console's ROM while on: SmasGame::setNesBrickBounce). Off by default.
  • Credits — where to find the author (YouTube, Reddit, GitHub; each opens in your browser).
  • CO-OP GAME on the title screens of Super Mario Bros., The Lost Levels and Super Mario Bros. 3: a third choice under 1 PLAYER GAME / 2 PLAYER GAME (MARIO GAME / LUIGI GAME; in SMB3 a fourth, under BATTLE GAME), picked with the game's own cursor. It starts a one-player game with co-op on (Luigi on controller 2); the game's own choices start without it. The choice sets the option below. In SMB1 and The Lost Levels the status bar's name reads MARIO & LUIGI during a co-op game, and the level card (WORLD 1-1) shows both brothers' heads; in SMB3 the status bar (in levels and on the map) shows a combined M L badge, x and the shared lives, and the map's WORLD box shows both brothers. A co-op game starts (or continues) with at least 10 lives, as the brothers share them.
  • Options → Multiplayer → Two-Player Co-op (SMB1, Lost Levels, SMB3) — Mario and Luigi play at the same time in Super Mario Bros. and The Lost Levels. Controller 1 has the character the game was started with (Mario, or Luigi in a Lost Levels Luigi game), controller 2 the other (by default the second controller, or I J K L, N jump, H run). The game's own player code runs a second time each frame with the other player's variables swapped in, so both move, jump, bump blocks, stomp enemies, get hurt, take power-ups and throw fireballs as the game's player does; in The Lost Levels each has his own physics and sprites (Luigi jumps higher and slides more). Objects that meet the player in their own code (lifts, springboards, firebars, hammers) run a second time for the other player, so both ride lifts, bounce on springs and get burnt. The world is shared. Whoever is further right moves the screen and the other is held at its left edge; the screen waits while the one behind is at that edge and still playing. Left idle (controller untouched for 3 seconds) while the other plays, he is brought to where the other last stood on the floor (or swims), can't be hurt by enemies, and is brought back rather than lost if he drops into a hole, until his controller is used again. He walks through the game's scenes too: the pipe intro (as before 1-2), and at the flag he slides down the pole if he reaches it and follows into the castle. Whoever takes Bowser's axe has the victory scene (Toad thanks him); the other comes along to Toad. The score is one shared score; after a game over, Continue goes on with the character the game was started with. Either can take a pipe, a vine or the flag: the game goes on with him and the other comes along after it. Lives are shared: a player who dies while the other plays on comes back beside him once that player is on his feet (on solid ground where there is some), small and blinking, for one life; with none left he sits out until the next area. When a player dies while the other plays on, his death tune plays and the area's music then carries on from where it paused (not from its start). Save states and rewind keep both players (see src/game/smb1coop.cpp).
  • Super Mario Bros. 3 co-op (the same option; see src/game/smb3coop.cpp) — Luigi on controller 2, run through the game's own player code with his own variables: his own form and power-ups, stomps, hits, the star, flying, picking up the goal card. Each enemy or item deals with whichever player is nearer (enemies' fireballs and hammers too; a kicked shell hits either, as in the original), or with the one playing while the other is left idle. Luigi throws his own fireballs and hammers, carries shells and slides down slopes. The screen follows the point between the two (both directions, and up for a flyer) and its edges hold them in view (the whole wide view in widescreen). A player whose controller has been left alone for 3 seconds rests: the screen follows the other, and the resting one is brought to where the other last stood when the screen leaves him behind (an auto-scroll's edge included), and nothing hurts him until his controller is used again (pits, lava and the time limit still count). Lives are shared. Either can die while the other plays on, as in SMB1's co-op: if Mario dies, Luigi takes over as the game's player (controllers and colours follow each brother). The one who died plays his death tune and jump, then comes back where the other stands, small and blinking. Either can take a pipe or a door, or grab the goal card or a Koopaling's wand: the other goes along, into the next area in the form he had. The map has Mario only; the level start card reads MARIO START! / LUIGI START!.
  • Co-op speed — the game's player code runs twice a frame in co-op, which slowed bu