{"id":51849941,"url":"https://github.com/felipedbene/ottd-macos9","last_synced_at":"2026-07-23T17:30:44.127Z","repository":{"id":372230837,"uuid":"1305956496","full_name":"felipedbene/ottd-macos9","owner":"felipedbene","description":"OpenTTD ported to Mac OS 9 / PowerPC (Retro68 toolchain)","archived":false,"fork":false,"pushed_at":"2026-07-19T19:25:51.000Z","size":9945,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-19T21:09:33.080Z","etag":null,"topics":["classic-mac-os","gcc","mac-os-9","openttd","port","powerpc","ppc","retro68","retrocomputing","transport-tycoon"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/felipedbene.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-19T18:54:43.000Z","updated_at":"2026-07-19T19:25:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/felipedbene/ottd-macos9","commit_stats":null,"previous_names":["felipedbene/ottd-macos9"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/felipedbene/ottd-macos9","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipedbene%2Fottd-macos9","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipedbene%2Fottd-macos9/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipedbene%2Fottd-macos9/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipedbene%2Fottd-macos9/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/felipedbene","download_url":"https://codeload.github.com/felipedbene/ottd-macos9/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/felipedbene%2Fottd-macos9/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35811417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-23T02:00:06.683Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["classic-mac-os","gcc","mac-os-9","openttd","port","powerpc","ppc","retro68","retrocomputing","transport-tycoon"],"created_at":"2026-07-23T17:30:43.223Z","updated_at":"2026-07-23T17:30:44.119Z","avatar_url":"https://github.com/felipedbene.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OpenTTD on Mac OS 9 / PowerPC\n\n![Platform](https://img.shields.io/badge/platform-Mac%20OS%208%2F9-lightgrey)\n![Arch](https://img.shields.io/badge/arch-PowerPC-blue)\n![Toolchain](https://img.shields.io/badge/toolchain-Retro68-orange)\n![Based on OpenTTD](https://img.shields.io/badge/based%20on-OpenTTD-green)\n![License](https://img.shields.io/badge/license-GPL--2.0-yellow)\n![Status](https://img.shields.io/badge/status-experimental-red)\n\nAn experimental port of [OpenTTD](https://www.openttd.org/) to **classic Mac OS 8/9 running on PowerPC**, built with the [Retro68](https://github.com/autc04/Retro68) cross-compiler toolchain.\n\nThis repository is the working scratch space for that port: a progression of small, individually bootable PPC applications that each prove one more piece of the game running on 25-year-old hardware — from a \"hello world\" up to the real OpenTTD engine simulating a growing town and the canonical game UI drawing itself, all in a single PowerPC binary.\n\n\u003e **Status:** experimental / research port. Everything described below has been confirmed on **real Mac OS 9 PowerPC hardware** (not just an emulator), unless noted otherwise. It is not a playable game yet — it's a milestone-driven journey toward one.\n\n---\n\n## What actually runs\n\nThe furthest-along build (`ottd-r1`) boots on Mac OS 9 / PPC and shows, all drawn by OpenTTD's *own* source (`viewport.cpp` / `window.cpp` / `widget.cpp` / `strings.cpp` / `toolbar_gui.cpp`):\n\n- an organic value-noise world — hills, a lake, a river, forests, industries;\n- **five towns growing live**, with real generated town names floating over them;\n- a moving vehicle;\n- the **full canonical OpenTTD toolbar** — real buttons, dropdown menus that open with real text;\n- a draggable, closeable in-game window;\n- a real player **company**, which lights up the build/finance/vehicle toolbar buttons.\n\nUnderneath, the real headless engine (`ottd-m1`) runs the genuine game loop: the calendar advances, a real `Town` lives in the real `TownPool`, OpenTTD's command dispatch executes real tile commands, and `GrowTown()` grows a town to 100+ houses with a real road network and population accounting.\n\n---\n\n## Screenshots\n\n**Real Mac OS 9 / PowerPC hardware** — the `ottd-r1` build running on the actual machine (captured over VNC).\n\nA real, moving economy: OpenTTD's own `CompanyFinancesWindow` — company \"Clamshell Transport\", pound-sterling balance, categorized revenue/expenses (loan interest, upkeep), max loan — over the live world, with a stats HUD (population, company money, industry cargo stockpile, stations). Real pooled `Company`, `Vehicle`, `Industry` and `Station` objects drive it, no fakes:\n\n![OpenTTD on Mac OS 9: the real finance window and a live economy](docs/screenshots/r1-finances-economy.png)\n\nThe full world with five live, named towns, a lake and a river, forests and industries — all rendered by OpenTTD's own `viewport.cpp` on PPC:\n\n![OpenTTD on Mac OS 9: full world with five named towns](docs/screenshots/r1-world-5-towns.png)\n\nThe canonical OpenTTD toolbar plus a zoomed-in town (Peningley) — houses, roads, a stadium, and autumn trees:\n\n![OpenTTD on Mac OS 9: full toolbar and a zoomed-in town](docs/screenshots/r1-toolbar-town-closeup.png)\n\nA draggable in-game \"Towns\" window, drawn by the real `window.cpp` / `widget.cpp` stack (Year 1950 · 5 towns · population 3250):\n\n![OpenTTD on Mac OS 9: the Towns info window](docs/screenshots/r1-towns-window.jpg)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eOffline render-pipeline previews\u003c/strong\u003e (host-side, used to debug geometry)\u003c/summary\u003e\n\nThese are **not** hardware captures — they come from the Python render simulators in `agent-compositor/` and `agent-tiles/`, which reproduce the port's isometric tile math on the host so landscape geometry and sprite selection could be debugged without burning hardware round-trips.\n\nComposited landscape scene (`agent-compositor/preview/scene.png`):\n\n![Composited isometric landscape render](agent-compositor/preview/scene.png)\n\nIndividual tile sprites the renderer selects and projects (`agent-tiles/previews/`):\n\n| Flat grass | Sloped grass | Water | Trees | Rocky |\n|:---:|:---:|:---:|:---:|:---:|\n| ![](agent-tiles/previews/grass_00_SLOPE_FLAT.png) | ![](agent-tiles/previews/grass_03_SLOPE_SW.png) | ![](agent-tiles/previews/water_flat.png) | ![](agent-tiles/previews/tree_0628.png) | ![](agent-tiles/previews/rocky_1_flat.png) |\n\n\u003c/details\u003e\n\n---\n\n## Subprojects\n\nEach directory is a self-contained CMake application built for PowerPC. Roughly chronological:\n\n| Directory | What it proves |\n|---|---|\n| `hello-ppc`, `hello-console` | Toolchain bring-up — first code running on PPC / Mac OS 9. |\n| `ottd-thread-demo` | Cooperative threading model (`std::thread` shim over the Mac event loop). |\n| `ottd-date-demo` | Real OpenTTD calendar/date math on PPC. |\n| `ottd-fileprobe` | POSIX `opendir`/`readdir`/`stat` backed by the Mac File Manager. |\n| `ottd-gfx-demo` | GRF sprite decode + the 8bpp blitter drawing real sprites. |\n| `ottd-landscape` | Landscape / ground-sprite rendering. |\n| `ottd-gamelogic` | Map + tile logic on the real data structures. |\n| `ottd-b1`, `ottd-b1min` | **B1** — first full one-shot landscape render (`b1min` = minimal bisection variant used to isolate linker crashes). |\n| `ottd-b2` | **B2** — a live `VideoDriver_MacClassic`: `WaitNextEvent` main loop, dirty-rect `CopyBits`, mouse pan/zoom/pick, plus the OS seams (sockets, dirents, cooperative sleep) and a permanent regression harness. |\n| `ottd-m1` | **M1** — the real OpenTTD engine running **headless** on PPC: date ticks, real `Town` pool, command dispatch, tile commands, roads, and a town that grows. |\n| `ottd-r1` | **R1** — the render merge: M1 engine + B2 video pipeline + the real OpenTTD window/UI stack + a real company, in one binary. The most complete build. |\n| `agent-compositor`, `agent-tiles` | Offline Python tooling — render simulators (PIL) and tile-sprite generation used to debug geometry without burning hardware round-trips. |\n| `compat` | The portability shims: `dirent.h`, `mac_sockets.h`, `libc_compat.h`, and cooperative `thread` / `mutex` / `condition_variable`. |\n\n---\n\n## OS seams\n\nPorting to classic Mac OS meant re-implementing the POSIX/runtime surface OpenTTD assumes, on top of Toolbox and Open Transport. Status:\n\n- **Video** ✅ — `VideoDriver_MacClassic` (`WaitNextEvent` + dirty-rect `CopyBits`, palette animation).\n- **File system** ✅ — `opendir`/`readdir`/`stat` via the File Manager (`PBGetCatInfo`).\n- **UDP sockets** ✅ — BSD `sendto`/`recvfrom` over Open Transport.\n- **TCP sockets** ✅ — non-blocking `connect`/`send` and `listen`/`accept`/`recv` over Open Transport (client + server, loopback-proven).\n- **Cooperative runtime** ✅ — `sleep_for` yields the CPU back to Mac OS via the event pump; condition-variable pumping still partial.\n\nA regression harness in `ottd-b2` re-runs the socket seam tests on every launch and reports one greppable verdict line each.\n\n---\n\n## Building \u0026 deploying\n\nPrerequisites: the [Retro68](https://github.com/autc04/Retro68) toolchain (built for `powerpc-apple-macos`) and its Open Transport SDK. The toolchain itself is **not** vendored here (see `.gitignore`).\n\nEach subproject builds with CMake against the Retro68 toolchain file, e.g.:\n\n```sh\ncd ottd-m1\ncmake -B build -DCMAKE_TOOLCHAIN_FILE=\u003cretro68\u003e/powerpc-apple-macos/cmake/retroppc.toolchain.cmake .\ncmake --build build --target ottdm1_APPL\n```\n\nThis produces a MacBinary (`.bin`) / PEF `.APPL` you copy to the Mac and decode. The larger builds (`ottd-m1`, `ottd-r1`) use a `build.sh` to hand-compile the real OpenTTD translation units into `obj/` first, with the port's merge flags, before the CMake link step. Runtime logging goes out over the UDP socket seam to a network log sink.\n\nThe checked-in deployable binaries (`*.APPL`, `*.pef`, `*.bin`, `*.ad`) are the actual artifacts that ran on hardware. Regenerable intermediates (`*.xcoff`, `*.o`, …) are git-ignored.\n\n---\n\n## Toolchain notes (the hard-won part)\n\nA sampling of the Retro68 / XCOFF-PPC landmines this port had to work around — the reusable gold:\n\n- **`--gc-sections` is a no-op** in this binutils XCOFF linker. Every compiled translation unit links *whole*, so pulling in one real OpenTTD `.cpp` drags its entire undefined-symbol surface. Bounding each unit with header-matched no-op stubs is mandatory, not optional.\n- **Duplicate symbols crash `ld` (SIGSEGV) instead of erroring cleanly.** \"Silent linker crash\" almost always means a `multiple definition` between a real TU and a stub — dedup with `#ifndef` guards.\n- **`dynamic_cast` on a real polymorphic object bus-errors** — RTTI is broken on Retro68/XCOFF PPC. Replaced with `static_cast` where the type is known and hand-written virtual `As*()` downcast helpers where the parser needs null-on-mismatch.\n- **`std::chrono::steady_clock` is broken** — swapped for a `TickCount()`-based clock.\n- **Bare `assert()` aborts silently** on Mac (no message reaches the log). A valid-looking op that just *stops* is usually a tripped assert — build with `-DNDEBUG` for release paths.\n- **Zeroed \"deadpool\" globals silently disable real code paths.** When a real flag won't fire, suspect an upstream `_settings_*==0` guard sitting in zeroed storage.\n\nThe `agent-*` Python simulators exist precisely because hardware round-trips are expensive — reproducing render/geometry bugs offline (via the real coordinate math) pointed straight at fixes without repeated deploys.\n\n---\n\n## Licensing\n\nThis repository is licensed under the **GNU General Public License, version 2** (see [`LICENSE`](LICENSE)).\n\nIt is a **port of, and derivative work based on, [OpenTTD](https://www.openttd.org/)** — which is itself GPL v2. This project compiles OpenTTD translation units, adapts OpenTTD source into its shim/scene files, and links OpenTTD code into every deployable binary (`*.APPL`, `*.pef`, `*.bin`). Because the whole is a work based on the Program, GPL v2 governs the whole, and the port code is offered under the same terms. There is no proprietary or permissively-licensed carve-out.\n\nAttribution for OpenTTD and the Retro68 toolchain is in [`NOTICE`](NOTICE).\n\n## Credits\n\n- [OpenTTD](https://www.openttd.org/) — the open-source Transport Tycoon Deluxe reimplementation being ported (GPL v2).\n- [Retro68](https://github.com/autc04/Retro68) — the GCC cross-compiler and runtime for classic 68k/PowerPC Mac OS that makes this possible.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelipedbene%2Fottd-macos9","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffelipedbene%2Fottd-macos9","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffelipedbene%2Fottd-macos9/lists"}