Native static recompilation core for SimCity on the Super Nintendo Entertainment System. Windows and Linux frontends are supported; the core builds on both platforms.
The original game ROM is not included. Use an externally supplied, legally
obtained ROM matching ROM-REQUIREMENTS.txt.
The Linux frontend running the live city in Wide Screen. The extra map is real city data on both sides, and the HUD and construction toolbar sit on the native columns the guest placed them on.
The settings overlay opens over the game frame — no second window, no font library, nothing to install but SDL2.
Cheats have their own submenu, because freezing money is not a display setting and burying it under mouse sensitivity made it easy to toggle by accident.
These are captured from the real frontend by
scripts/capture-screenshots.py, which runs it on a virtual display and drives
it with synthetic input — the images are not mock-ups and cannot drift from
what ships.
SimCity's executable W65C816 game instructions were analysed and translated into generated native C before the application was built. Production dispatch uses exact processor-state and program-counter contexts. It contains no general-purpose SNES CPU interpreter, runtime opcode decoder, dynamic recompiler, JIT, or automatic emulator fallback.
The audio program is static too. SimCity's exact S-SMP program-counter/opcode authority dispatches only compiled SPC700 instruction forms. Its protected-code bitmap rejects writes to statically owned driver code, and unknown execution or semantic ARAM reads stop with a diagnostic. The former emulator S-DSP runtime has been removed. A project-owned fixed 32-phase S-DSP implements register timing, BRR decoding, Gaussian interpolation, envelopes, noise, pitch modulation, echo/FIR and signed 16-bit stereo PCM at the native 32,040 Hz rate.
Game simulation, graphics, samples, music and effects are not prerecorded. They remain live state driven by the external ROM, cartridge memory, WRAM, VRAM, ARAM, controller input and SNES timing.
The complete runtime includes:
- Generated exact-context W65C816 game-code dispatch.
- Native cartridge, WRAM, bus, DMA, HDMA, controller and CPU-I/O handling.
- Native PPU registers, scanline events, rendering and framebuffer output.
- Exact rational NTSC scheduling and one guest frame per host deadline.
- Fail-closed exact-PC S-SMP AOT and project-owned 32-phase S-DSP.
- Native 32,040 Hz stereo PCM with knownness, overflow and hash diagnostics.
- Battery SRAM and deterministic snapshots including continuing audio state.
- A Windows launcher (Win32/GDI, SDL3 gamepad, DirectSound) and a Linux frontend (SDL2, windowed) with gamepad support, arbitrary window sizing and an optional pointer-driven guest cursor, tested on Steam Deck.
- Windowed game-frame screenshots and exact fullscreen-presentation captures.
Wide Screen is a game-specific core feature, not frontend stretching. The core
can render 398x239: the original 256-pixel view plus 71 real city-map pixels on
each side. It extends BG1/BG2 sampling, camera limits, the map cursor and
building placement while keeping the HUD and toolbar anchored correctly.
Title, setup, tutorial prompts, scenario selection and modal screens retain
their native layout. The toolbar control is enabled by default, persists in
settings.ini, and can be changed while a game is loaded.
Version 1.4.0 ports the current Jungle Strike frontend architecture while retaining and adapting SimCity's widescreen controls and dynamic geometry. Win32/GDI owns windows and presentation. SDL3 is used only for gamepad access.
The static core produces 32,040 Hz PCM from guest time. The host drains PCM during long guest frames, applies the selected nearest, linear or cubic-Hermite speaker resampler, and writes a DirectSound ring buffer. The playback design is based on the proven Mesen approach: cursor-derived latency measurement, pre-roll, bounded drift correction, recovery and exact rational frame pacing. The default speaker rate is 48,000 Hz. Extra forced latency is disabled by default and, when enabled, ranges from 0 to 40 ms. Host output changes never alter the core's native PCM authority.
Mesen was used as the hardware-behaviour and frontend-timing reference during development. Snes9x-derived S-SMP execution semantics remain under their original license and are restricted to the generated fail-closed SimCity AOT authority. Neither emulator is embedded as a runtime fallback.
The Linux frontend uses SDL2 for window management, rendering and audio. It
accepts the ROM path via command-line argument or the SIMCITY_ROM_PATH
environment variable. It is tested on Steam Deck (SteamOS, x86_64), where it
holds the native 60.0988 Hz frame cadence at 1280x800 with widescreen on.
./simcity-linux --rom /path/to/SimCity\ \(USA\).sfc| Option | Values | Default | Description |
|---|---|---|---|
--rom <path> |
file | required | Path to SimCity (USA).sfc ROM |
--resolution <N> |
0-3 | 0 (480p) | 0=480p, 1=720p, 2=800p, 3=1080p |
--size <WxH> |
e.g. 1280x800 |
— | Arbitrary window size; overrides --resolution |
--widescreen |
flag | off | Enable 398x239 core widescreen output |
--soft-mouse |
flag | on | Drive the guest d-pad cursor from the host pointer (on by default; the flag is now redundant but kept for compatibility) |
--mouse-sens <N> |
1-64 | 2 | Soft-mouse threshold, texture px per frame |
Press F1, or both stick clicks together, in game to open the settings overlay. It is drawn on top of the game frame with a built-in 5x7 bitmap font, so the frontend needs no font library and no TTF file — only SDL2. Navigate with the arrow keys or the d-pad (including on Steam Deck): Left/Right changes a value, B activates.
The menu pauses the guest: no frame advances and no audio drains while it is open. Advancing would spend money or scroll the city underneath the settings being changed.
Both the settings menu and the CHEATS submenu are full-screen overlays.
| Row | Effect |
|---|---|
| Resolution | 480p / 720p / 800p / 1080p, applied to the live window |
| Widescreen | Toggles the 398x239 core output |
| HUD shift X | −142..+142 px, moves the in-game HUD and toolbar. Defaults to -71, which cancels the widened map margin and restores the HUD to its native column; 0 is the old, displaced position |
| Soft mouse | Toggles pointer-driven cursor (on by default) |
| Mouse sens | 1-16, lower is more sensitive |
| Color | SWAP R/B (default) or NORMAL |
| Cheats | Opens the submenu |
| Resume / Quit | — |
In the cheats submenu, B confirms a one-shot action or toggles the selected value row, and X (A on the pad) goes back. Both are edge-triggered, so holding B toggles once rather than flipping every frame.
The frame is presented at the largest whole-number scale that fits the window, centred, with nearest sampling, so each guest pixel stays a sharp square and the aspect ratio stays correct (398x239 is 1.67:1; stretching to a 4:3 window would distort it). Any leftover border is left as background.
Linear filtering was tried and rejected: it turned every pixel into a blur, which is the opposite of what this content wants.
Settings persist to settings.ini on exit and are read at startup. The file
uses the same [General] section and key names the Windows launcher writes, so
one file works on both frontends. Command-line options override the file.
The in-game HUD — status bar, construction toolbar, message box — is drawn from OAM sprites that the guest places in native 256-pixel screen space. In the widened view the city map gains 71 px on each side, and every sprite is moved by that margin so world objects stay registered with the map. That same 71 px also moves the HUD, which is why the toolbar sits away from the edge when widescreen is on and is correctly placed when it is off.
No field in an OAM entry separates HUD chrome from world objects: index, y band, priority and palette all overlap. The guest does mark the one exception in WRAM, though — while map focus is active, OAM 0–3 are the map cursor, and everything else that is live is chrome. The renderer therefore takes the offset for every sprite except the map cursor, which keeps its own map-registered displacement.
No OAM index threshold is used to make that split. One would tear any chrome sprite straddling it, and one did: the tutorial mayor spans OAM 0..27 and was split down the middle by an earlier index-based rule.
The value is in pixels, applies only while widescreen is on, and leaves the city
map itself untouched: at -71 the map region is pixel-identical, and the map
cursor keeps its own displacement.
It ships defaulted to -71, which cancels the margin exactly and is what a
player sees on a fresh install. headless-profile --hud-shift 0 does the same
for A/B against the pre-T050 renderer.
The overlay now occupies the full window area instead of only the bottom‑right corner. Navigation remains with arrow keys / d‑pad; B activates a row.
Only cheat addresses verified against this core are offered. Funds sit at
WRAM $0B9D as a 24-bit little-endian value; this was confirmed by reaching a
live city and observing $004E20, the documented $20000 starting balance.
Addresses used by other emulators for instant-build and disaster toggles were
deliberately left out: they are unverified here and would silently do nothing.
Known issue: the money cheat (F1 → Money) does not take effect in the current build; investigation in progress.
--soft-mouse maps the host pointer onto the guest's own cursor by synthesising
d-pad presses from per-frame pointer motion. The OS cursor is hidden while it is
on, because the guest draws its own.
The pointer buttons drive the guest face buttons: left mouse is A, right mouse is B. The title has no SNES Mouse peripheral, so this is the only mouse-shaped behaviour available for confirming actions.
This is deliberately not a SNES Mouse emulation. That peripheral would have to
be answered on a controller port, and the SimCity ROM never asks for one: a
mouse is distinguished from a pad by reads past bit 15 ($4219/$421A/$421B),
and the game reads $4218 only — two ordinary 2-byte controller reads. Driving
the guest's d-pad cursor is the only mouse-shaped behaviour this title can use.
Motion is mapped by rate, not by position feedback. The core exposes cursor X
($025D, $01EB) but has no cursor Y, and guessing that address would steer the
cursor diagonally into map edges. Rate mapping needs no guest state, at the cost
of no self-correction: if the guest's step size differs from pointer speed the
cursor lags slightly. Keyboard and gamepad d-pad always take priority, so the two
input paths cannot fight over the cursor.
Keyboard controls:
| Key | Action |
|---|---|
| Arrow keys | D-pad |
| Z | B |
| X | A |
| A | L |
| S | R |
| Return | Start |
| Backspace | Select |
| Q | Y |
| F1 | Toggle the settings menu |
| Escape | Close the menu, or quit |
On a Steam Deck both stick clicks together also toggle the settings menu, so it is reachable without a keyboard. The shortcut fires on the edge only, and it is checked before the game reads the pad, so pressing both sticks never also acts on the game.
On systems where the renderer cannot access /dev/dri/ directly (headless or
unprivileged environments), force software rendering:
SDL_VIDEO_RENDERER=software ./simcity-linux --rom /path/to/rom.sfc| Package | Ubuntu/Debian | Fedora | Arch | openSUSE |
|---|---|---|---|---|
| CMake >= 3.20 | cmake |
cmake |
cmake |
cmake |
| GCC / Clang | gcc g++ |
gcc gcc-c++ |
gcc |
gcc gcc-c++ |
| SDL2 devel | libsdl2-dev |
SDL2-devel |
sdl2 |
SDL2-devel |
libsdl2-dev is required, not optional: the Linux frontend is written against
the SDL2 API and has no SDL3 or Vulkan path. Without it, CMake stops at
configure time and names the package to install. To build only the portable
core and the headless test, skip the frontend:
cmake -S . -B build -DBUILD_LINUX_FRONTEND=OFFA ROM matching ROM-REQUIREMENTS.txt is needed at runtime but is never
distributed with the build.
curl -fsSL https://raw.githubusercontent.com/linuxkafe/SimCity-SNES-Static-Recomp/main/scripts/install-deck.sh | shThe script:
- downloads the pre‑built binary (verified with SHA‑256) from the GitHub release page, falls back to building from source if the download fails,
- installs any missing build dependencies (
base-devel cmake git pkgconf glibc linux-api-headers sdl2-compat) on the Deck, - asks for the ROM path (
~/simcity-data/SimCity.sfc), - compiles (or uses the pre‑built binary) and creates a
run.shlauncher, - registers a Steam shortcut (F1 opens the settings overlay; both stick clicks together also open the menu),
- creates a desktop entry for desktop mode.
After the first run the COLOR menu item is set to SWAP R/B (the default that works on the Deck). Change it to NORMAL if your display shows the correct colours without swapping.
The binary is pre‑built and verified – it contains no ROM data (verified by scripts/verify-release.py). If you prefer to build from source, run the installer with --from-source or compile manually as shown below.
The static-recomp core compiles natively on the Steam Deck (x86_64, SteamOS holo). SDL2 is pre-installed on SteamOS.
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)Run with:
./build/frontend/linux/simcity-linux --rom /path/to/SimCity\ \(USA\).sfc --resolution 2 --widescreenFor the best experience, use the provided launcher:
# Copy ROM to data directory
mkdir -p ~/simcity-data
cp /path/to/SimCity\ \(USA\).sfc ~/simcity-data/SimCity.sfc
# Run from Gaming Mode application launcher
# "SimCity SNES Static Recomp" appears in Games categoryOr via script:
~/simcity-data/run_simcity.shThe launcher configures:
- Resolution: 800p (1280x800) — optimal for Deck's 1280x800 display
- Widescreen: Enabled (398x239 core output)
- Video driver: Wayland (via gamescope)
SDL_VIDEODRIVER=dummy ./build/frontend/linux/simcity-linux --rom "/path/to/SimCity (USA).sfc" --resolution 0
# Gamepad connected: Steam Deck ControllerThe default is SWAP R/B, which is what reads correctly on the Steam Deck: the
controller logo shows A red and X blue, and the in-game R/C/I are right. Set
COLOR to NORMAL in the menu to get the raw core channel order instead, or
use --swap-rb / --normal-colors. The choice is stored in settings.ini as
ColorMode.
The frontend uploads 0xAARRGGBB through SDL_PIXELFORMAT_ARGB8888, and every
automated check says that reproduces the core byte for byte on the accelerated
renderer, through Wayland, and through gamescope. SWAP R/B therefore compensates
for something downstream of the renderer that those captures could not show; it
exchanges the red and blue byte of every pixel at upload time and leaves the rest
of the pipeline untouched.
The frame is uploaded as SDL_PIXELFORMAT_ARGB8888, matching the core's
0xAARRGGBB output. ARGB8888 and XRGB8888 were both measured on the OpenGL
renderer and both reproduce the core byte for byte; ABGR8888 transposes red
and blue. If the picture looks wrong, run:
./build/frontend/linux/simcity-color-ground-truth "/path/to/SimCity (USA).sfc" exactIt re-derives the expected channel order from the SNES BGR555 hardware format rather than from the core's own output, so a swap inside the core cannot pass, then reads the frame back through the renderer and reports any pixel that differs. To capture what the renderer actually produced rather than the core's framebuffer:
./build/frontend/linux/simcity-linux --rom "/path/to/SimCity (USA).sfc" \
--screenshot /tmp/frame.ppmOr use the headless test binary (no window, no audio):
./build/frontend/linux/headless-test "/path/to/SimCity (USA).sfc" 300
# OK: 300 frames advanced successfully
# Current frame: 300
# Instructions: 3798805
# Master clock: 107159420Not implemented. SDL2 is used on all platforms. SDL3 was evaluated and rejected for now: its 2D renderer and audio APIs differ from SDL2's, so a correct port is a real port rather than a build-flag change. SDL3 also still carries the personal-use-only Snes9x terms noted under Licensing, so adding it is a decision that should be made deliberately rather than by accident.
| Issue | Status | Workaround |
|---|---|---|
| Video driver only works in Gaming Mode | Expected | Run from Gaming Mode, not Desktop/SSH |
| SDL2 only; no Vulkan path | Known gap | SDL3's 2D renderer differs from SDL2's API and is not implemented here |
| SSH/X11/Wayland fail outside gamescope | Expected | Use SDL_VIDEODRIVER=dummy for headless test |
deploy-linux.sh is the single supported convenience path. It always
configures Release, builds, and stages dist/linux/ with the binary and a
run.sh that forwards any extra options:
./deploy-linux.sh # build Release, stage dist/linux/
./deploy-linux.sh --deck HOST # additionally scp to HOST:~/simcity-build/run.sh passes options straight through:
dist/linux/run.sh rom.sfc --size 1280x800 --widescreen --soft-mousePlain cmake remains the source of truth if you would rather drive the build
yourself.
A prebuilt Linux binary is safe to distribute: it carries no game data.
scripts/make-release.sh does not assert that, it proves it. Given the ROM, it
checks that no 4 KiB slice of the ROM appears anywhere in the binary, that there
are no large repetitive regions suggesting embedded data, that the binary
refuses to start without a ROM, and that it rejects a correctly-sized file with
the wrong contents:
ok nenhuma das 33 fatias de 4096 bytes da ROM aparece no binario
ok sem regioes grandes e repetitivas que sugiram dados embutidos
ok recusa arrancar sem ROM (pede --rom)
ok rejeita um ficheiro de tamanho certo mas conteudo errado
O binario pode ser distribuido: nao contem dados do jogo.
It writes dist/linux/simcity-linux, a .sha256, and a release.json
recording "requires_rom": true and "rom_shipped": false.
These artifacts are deliberately not committed to git. build*/ and
dist/ are ignored, and that is the right place for them: a 9 MB executable in
history is permanent bloat that cannot be cleanly withdrawn later, it cannot be
reviewed, and it goes stale against the sources it was built from. Ship binaries
through make release or a GitHub Release, and let release.json carry the
proof.
The ROM stays external and unmodified. That is the project's release invariant
(Wide Screen - 1.4.0.txt) and this does not change it.
Frame budget on the Steam Deck is 16.641 ms (60.0988 Hz NTSC).
simcity_recomp_advance() performs the real render internally; a second
call to simcity_recomp_render_current_frame() then hits the full-state frame
cache and costs almost nothing. Any tool that times those two calls separately
and labels them "advance" and "render" is reporting the render cost under the
wrong heading. Measured directly against simcity_recomp_advance_headless(),
which passes render_frame = 0:
| Component | Cost per frame |
|---|---|
Emulation (advance_headless, no render) |
3.57 ms |
| Rendering | ~10.5 ms |
| Total | ~14.1 ms |
Rendering is roughly 75 % of the frame. headless-profile grew a
--no-pc-profile flag so timings can be taken without the per-instruction PC
histogram, which is otherwise active during every run.
| Configuration | Per frame | Observed |
|---|---|---|
-O0 build, frame rendered twice |
~105 ms | ~10 fps |
-O3 Release, frame rendered twice |
~34 ms | ~29 fps |
-O3 Release, single render |
~14.1 ms | ~71 fps |
-O3 Release, emulation only |
~3.6 ms | ~280 fps |
Median of six runs over 950 frames. The earlier ~15.4 ms / 57.4 fps figure predates the per-pixel optimisations below.
The background sampler runs three times per pixel, so its arithmetic dominates. Three changes, each verified bit-identical by comparing frame hashes over 950 frames:
background_pixeldivided by runtime values four times per pixel. The map is always 32 or 64 cells and the tile size always 8 or 16, so every divisor is a power of two and the results are provably unchanged by shifts and masks. −14.7 %.- The same substitution in
city_background_pixel(widescreen sampler). No measurable effect on the headless benchmark, because the widescreen city view is never reached in those 950 frames; kept because it is provably equivalent and removes four divisions per pixel from the live city view. - ~15 PPU constants (mode, bpp, layer size register, map base, character base, tile size, world extents, mosaic parameters) were recomputed on every pixel although they depend only on registers latched per scanline. They are now computed once per line per layer. −9.1 %.
Render-path work is now ~10.5 ms of the ~14.1 ms frame. What remains in
background_pixel is genuine VRAM tilemap and tile fetch.
Link-time optimisation was evaluated and rejected: it changed the measured time by ~0.6 %, within run-to-run noise, and cost a 4× build-time increase.
The remaining wait tail is why 60 fps is reached but not locked: SDL_Delay
has roughly millisecond granularity and tends to overshoot.
Two further problems were compounding:
-
Unoptimised build. With no
CMAKE_BUILD_TYPEthe core compiled at-O0. The build system now defaultsCMAKE_BUILD_TYPEtoRelease; explicitly select it for any performance measurement. -
Every frame was rendered twice.
simcity_recomp_advance()performs the host frame conversion itself, and the frontend then calledsimcity_recomp_render_current_frame()on top of it. The frontend now advances withsimcity_recomp_advance_headless()and converts exactly once. The two routes were verified to produce byte-identical framebuffers over 600 frames in both display modes. -
Audio backlog, not underrun. The SDL device buffer was 8192 frames, which is 256 ms of slack at 32,040 Hz. SDL drains PCM in real time, so a quarter-second backlog is permanent, audible latency. The device buffer is now 512 frames (16 ms), PCM is handed over with
SDL_QueueAudio, and surplus is discarded per frame to bound drift.Measured end-to-end queue occupancy on the Deck over 58 samples: min 16.6 ms, median 22.1 ms, max 33.3 ms, with the core-side backlog at zero throughout. That is the buffering actually in front of the speaker; the 512-frame figure is only the device buffer, not the whole latency.
Audio reaches the device with SDL_QueueAudio from the main thread. The
callback form let SDL's audio thread read the core's PCM ring while the main
thread was still writing it in audio_sink(), which was a data race; queueing
keeps one writer and one reader on different objects without holding a lock
across the whole frame.
Per-frame SHA-256 of the framebuffer is diagnostic metadata with no consumer outside the renderer, and cost ~3 ms per frame. It is now computed only while a static-core log is open.
This repository currently ships no LICENSE file, and none can be asserted
here. This section records the facts rather than granting terms.
- The project is derived from an upstream repository (
Junior-Jones/SimCity-SNES-Static-Recomp, reachable via theupstreamgit remote). Its terms govern what this distribution may do; they have not been verified here. static-recomp/static-audio/snes9x-bapu-aot/contains retained Snes9x SPC700 execution semantics. The bundledSNES9X-LICENSE.txtis not an OSI-approved licence. It states Snes9x is "freeware for PERSONAL USE only" and that commercial users "should seek permission of the copyright holders first".- Because of that embedded restriction, this combined work cannot be relicensed under a permissive licence such as MIT, BSD or Apache by the project alone, and commercial redistribution is not clearly permitted.
SDL3(zlib) and the project-owned S-DSP are separable and are documented inTHIRD-PARTY-NOTICES.txt.
Anyone wishing to publish or redistribute this must first resolve the Snes9x personal-use-only clause with its copyright holders, and confirm the upstream terms. That is a legal decision for the copyright holder, not a build setting.
simcity_recomp_write_wram() lets a frontend poke guest WRAM between frames,
which is how cheats and mods are implemented. It is the write counterpart to the
existing bounds-checked simcity_recomp_read_wram().
uint8_t money[3] = { 0x3F, 0x42, 0x0F }; /* 999999 */
simcity_recomp_write_wram(game, 0x0B9D, money, 3);Contract, and the parts that are easy to get wrong:
| Rule | Reason |
|---|---|
Call from the thread that calls simcity_recomp_advance() |
the core cannot observe a concurrent host write |
| Call between frames, never during one | a write mid-advance is a data race |
| Nothing is written when the call returns 0 | a rejected write must not leave WRAM half-modified |
| Range must lie inside the 128 KiB image | offsets at or past 0x20000 are rejected |
The write is visible to the next frame as if the guest had stored those bytes. Battery SRAM, S-SMP and S-DSP state are untouched, and later snapshots capture it because WRAM is part of the saved runtime image.
Do not poke PPU or camera state. The core caches widescreen cursor anchors
in the instance rather than in WRAM, so writing $01BD, $0139, $01EB or
$025D behind its back desynchronises that cache. Cheats should target game
state such as funds at $0B9D.
static-recomp/tests/test_wram_write.c pins the bounds contract, the
no-partial-write guarantee, the round trip, and that the static route survives a
poke. It runs under ctest when -DSIMCITY_TEST_ROM=<rom> is configured.
Tracked as tickets under aes/tickets/ following a four-persona adversarial
review. The ones that affect a user today:
| Ticket | Effect |
|---|---|
| T004 | On a host without system SDL2, CMake reports success and the build then fails. |
| T005 | Audio back-pressure drops all queued PCM rather than the surplus, causing audible gaps. |
| T006 | The settings menu cannot be opened on Steam Deck without a keyboard. |
| T008 | Quitting discards the saved city: battery SRAM is never written on Linux. |
| T002 | README (earlier revision) pointed at a launcher script that is not in the repository. |
| T007 | No CI job builds the Linux frontend, which is how T004 shipped. |
Fixed in the review round: the red/blue channel swap (B1), --resolution being
discarded (B2), the inert FREEZE MONEY row (B3), settings.ini deleting every
Windows-launcher key (B4), a frozen pointer delta steering the menu (B5), divergent
MouseSens bounds (T009), and a README code fence that swallowed three sections
(T010).
The source includes contract tests for controller ordering, configuration, resampling, audio defaults, project-owned DSP phase timing, linked DSP purity and real-ROM snapshot PCM continuation. Long headless routes cover neutral execution, tutorial gameplay, HUD transitions, toolbar focus, map edges, wide-cursor travel, construction, scenarios, Freeland and all four map corners. Unknown static CPU/audio states and PCM overflow remain release failures.
Third-party notices and licenses are in THIRD-PARTY-NOTICES.txt and the
corresponding source directories.


