Skip to content

libretro: Dreamcast Now presence + DreamPi-compatible config server + community DNS - #2533

Open
rpf16rj wants to merge 3 commits into
flyinghead:masterfrom
rpf16rj:dcnow-dreampi
Open

rpf16rj wants to merge 3 commits into
flyinghead:masterfrom
rpf16rj:dcnow-dreampi

Conversation

@rpf16rj

@rpf16rj rpf16rj commented Oct 5, 2026

Copy link
Copy Markdown

Summary

Adds the missing pieces that make libretro Flycast behave like a real DreamPi-equipped Dreamcast for the community service ecosystem — no external Pi required:

  • Dreamcast Now presence (reicast_dcnow): reports the running session to dreamcast.online with a stable player identity. The ID is a SHA-256 of a normalized MAC-derived identity, persisted in flycast_dcnow.id (save dir), so the same player keeps the same ID across sessions and can claim it on the site.
  • DreamPi-compatible config server on :1998: emulates the HTTP endpoint of DreamPi's config_server.py — GET returns the JSON Dreamcast Now expects, and the built-in browser page lets the user view the player ID and set a custom MAC / enable-disable presence without editing option files.
  • Configurable MAC identity (reicast_dcnow_mac): auto by default; a literal XX:XX:XX:XX:XX:XX value (or enabled for the generated identity) can be set through the options file or the :1998 page, since libretro core options are enum-only and can't accept free text.
  • Selectable community DNS (reicast_dns_server): intercepts the emulated Dreamcast's DNS queries and forwards them to dns.flyca.st, Shuouma (46.101.91.123), the alternate DreamPi DNS (209.50.50.129), or standard DNS — covering the services DreamPi users normally get for free.

Why

On DreamPi hardware all of this is "automatic": presence on dreamcast.online, the config endpoint that the site uses to find and validate the device, and DNS redirection to the community servers. Console/embedded ports (and headless libretro frontends) have no way to reproduce any of it today — the only options are buying/building a DreamPi or running the emulated Dreamcast behind one. This gives every libretro user the same experience natively.

Windows portability fixes included

Building the feature on Windows/mingw surfaced two real portability bugs, fixed in this PR:

  • net_platform.h: SHUT_RDWR was unmapped on Winsock (SD_BOTH)
  • Missing libc headers that clang/libc++ requires where GCC tolerates (option.h, oslib.h, rtl8139c.cpp)

Verified: builds clean with llvm-mingw (clang 23) producing a working flycast_libretro.dll with all libretro exports, and on the libretro fork CI targets.

Files

core/cfg/option.*, core/network/{CMakeLists.txt,dcnow.cpp,dcnow.h,net_platform.h,picoppp.cpp}, shell/libretro/{libretro.cpp,libretro_core_options.h,option.cpp} (+ small include fixes in oslib.h, rtl8139c.cpp, option.h)

Same change set as sysfce2#186 (the libretro mirror), submitted here so it lands upstream first.

Generated with Devin

rpf16rj and others added 3 commits October 3, 2026 12:50
…ity DNS

Replicates inside the core what a DreamPi (Kazade/dreampi) does beside a
real Dreamcast:

- reicast_dns_server core option picks the resolver handed to the
  emulated console over PPP (dns.flyca.st / Shuouma 46.101.91.123 /
  DreamPi alternate 209.50.50.129 / 8.8.8.8). The legacy
  46.101.91.123->dns.flyca.st rewrite is removed so an explicit choice
  is honored literally.
- reicast_dcnow: UdpSink snoops the Dreamcast's DNS queries and a worker
  POSTs sha256(hostname) to dcnow-2016.appspot.com every 15 s over plain
  HTTP/80, like dcnow.py; shared domains post once per session.
- Port 1998 answers the DreamPi config_server.py JSON with CORS so
  dreamcast.online/now detects the emulator as a DreamPi; browser GETs
  get a config page and POST accepts mac=/enable/disable, which is also
  the only way to set the MAC without editing files (core options are
  enum-only).
- reicast_dcnow_mac: 'auto' uses/generates flycast_dcnow.id in the save
  dir; a literal AA:BB:CC:DD:EE:FF claims a specific identity (e.g. a
  real DreamPi's MAC); uppercased before hashing like the Pi's %012X.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
dcnow.cpp shuts down the :1998 listen socket with SHUT_RDWR to break the
accept loop; Winsock spells it SD_BOTH, so map it alongside the existing
SHUT_RD/SHUT_WR definitions. Needed to build the feature on Windows/mingw.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
option.h: pull <cstring>/<cstdlib> in before namespace config — option_lr.h
is included inside 'namespace config', so any header it includes there
creates a nested config::std on toolchains where the headers were not
already pulled in (clang/libc++), breaking every std:: lookup in the file.

rtl8139c.cpp: <cstdlib> for calloc/free.
oslib.h: <malloc.h> on _WIN32 for _aligned_malloc/_aligned_free.

No functional change; needed to build the core with llvm-mingw.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@flyinghead

Copy link
Copy Markdown
Owner

I am not sure the team behind Dreamcast Now/DreamPi would agree or be happy with this integration. Did you reach out to them to get their feeling?
Also, why only libretro? What about Flycast standalone?
Finally, I haven't looked at the code in detail but this should go to the dev branch first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants