GitHub - borancar/Ducks · GitHub
/" data-turbo-transient="true" />
Skip to content
Type / to search
Sign in<br>Sign upAppearance settings
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
borancar
Ducks
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
master
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>159 Commits<br>159 Commits
.clang-format
.clang-format
.gitignore
.gitignore
LICENSE
LICENSE
Makefile
Makefile
README.md
README.md
dos_io.c
dos_io.c
egg.c
egg.c
game.c
game.c
game.h
game.h
sdl_io.c
sdl_io.c
sound.c
sound.c
View all files
Repository files navigation
Ducks! — the game's own code, reconstructed
C reconstructed from the disassembly of Ducks! v1.2 (Tim Furnish / Hungry<br>Software, 1998-2000), one file per unit of the original we can argue for. It<br>builds and plays:
make run
You need your own copy of the game, and make run will fetch it for you.<br>Nothing of Ducks! is distributed here — no executable, no .egg data, no artwork.<br>What make run does is download the archive from an archive page,<br>https://www.kieranmillar.com/ducks/, and keep the one file the port needs:<br>Eggs/Main.egg, which holds every picture, level, sound and line of text in the<br>game. That page is not the authors' — it is where a copy can still be found.
It needs curl and 7z, does nothing if Eggs/ is already there, and does not<br>touch the network at all if DUCKS_GAME_DIR points at a copy you already have.<br>make on its own just builds; make eggs just fetches; clean deliberately<br>leaves Eggs/ alone.
What you need
A C compiler, make, and SDL3 — not SDL2; the two are not interchangeable and<br>the build looks for pkgconfig(sdl3). curl and 7z are needed only by<br>make eggs, to fetch the game data.
Fedora<br>sudo dnf install gcc make pkgconf-pkg-config SDL3-devel curl 7zip
Debian / Ubuntu<br>sudo apt install build-essential pkg-config libsdl3-dev curl p7zip-full
Arch<br>sudo pacman -S base-devel sdl3 curl p7zip
macOS<br>brew install sdl3 sevenzip (compiler from the Xcode command line tools)
The Fedora line is the one this was built with; the others are the usual names<br>for the same four things. If a package has been renamed, what you want is the<br>SDL3 development package — the one that installs SDL3/SDL.h and an sdl3.pc.<br>Check it with:
pkg-config --modversion sdl3
Debian and Ubuntu only started carrying libsdl3-dev recently (trixie, 24.10).<br>On anything older, build SDL3 from https://github.com/libsdl-org/SDL. SDL2 is<br>not a fallback: the port uses SDL3's audio streams and its<br>SDL_GetKeyFromScancode with a modifier state.
What this is
The original sources are not available. This is what the code must have looked<br>like for the compiler to have emitted what it did: the game's own code segment,<br>0x04ca0-0x14620, read back out of the disassembly. Every routine in it is<br>transcribed and nothing stands in for one.
Every function carries the image offset it was read from, so any line can be<br>checked against the binary, and where a name or a type is a guess it says so.
Two backends, one interface. game.h declares what the game needs from below<br>it; dos_io.c is the original reconstructed - VGA ports, Mode X planes, INT 33h -<br>and sdl_io.c is the same interface on SDL3. The game cannot tell which one it is<br>linked against, which is the test of whether the split was drawn in the right<br>place.
dos_io.c is a record rather than a second build: reimplementing the DOS side is<br>not the aim, so it holds what we know about the original's hardware layer - the<br>Mode X planes, the DAC, the CRTC, INT 33h - and the Makefile does not compile it.
Written as C99, not as period C. The aim is a port that builds and runs, so a<br>construct is written the clearest modern way that matches the instructions. It is<br>not an attempt to feed Turbo C++ 3.0 something byte-identical.
Files
file<br>what is in it
game.c<br>the game: main and init, the resource and string loaders, the fonts, every menu and screen, the save format, the hall of fame, the level loader, the frame, every entity's behaviour, the tools, the particles, the endings and the cutscenes. In address order, which is the order the compiler emitted them
game.h<br>its types, its globals, and the interface both backends implement
sdl_io.c<br>that interface on SDL3: a linear framebuffer, an SDL palette, a 70 Hz deadline in place of the retrace spin, the mouse, the audio device
dos_io.c<br>that interface as the original: BIOS mode, Mode X planes, the DAC, the page flip, INT 33h, and every drawing primitive
sound.c<br>the sound module: the id-to-sample map, the eight voices, and the original's additive mixer
egg.c<br>the egg reader: the directory, the chunk decoder, the shifted-string...