Giter VIP home page Giter VIP logo

sundog's Introduction

CI status

Sundog: Frozen Legacy

Sundog box logo

This is a port of the Atari ST game SunDog: Frozen Legacy (1985) by FTL software to modern platforms, using SDL2 for input and OpenGL ES 2+ for graphics. A good overview of the gameplay can be found on wikipedia.

The game was originally written in Pascal, developed using the well-known UCSD Pascal compiler. This compiler compiles to bytecode called "p-code" for an abstract architecture called the p-system. This project implements a p-system interpreter (also called "P-Machine Emulator" or PME) in C, which is able to run the game.

This makes it possible to run the game without emulating the Atari ST or even 68000 processor. There are a few assembly-language functions for (primarily) graphics rendering, which have been re-implemented separately.

The goal of this port is to keep the gameplay and graphics close to the Atari ST version, although small hacks or improvements would be welcome. See the Sundog Resurrection project for a complete re-imagining of the game.

Screenshots

Title screen Planet surface Drahew city Drahew exchange Ship interior Inside pod Pilotage Ship maintenance Space fight

Disk image

For copyright reasons this game does not come with the resources nor game code. It requires the user to provide a 360K .st raw disk image of the game to run. This can be imaged from an original copy or found on a dozen abandonware sites. Be sure to use an image of the original disk: the re-packed version will not work as the layout of the disk will be different.

Unlike the original game which writes to disk on every start, this implementation never writes to the disk image.

Building from source

Linux

To build from source make sure the SDL2 development package for your distribution is installed, as well as GNU readline (only necessary for the debugger). On Debian and Ubuntu this is:

apt-get install libreadline-dev libsdl2-dev meson ninja-build

Then:

meson setup --buildtype release build
ninja -C build

Mac OS X

  1. Install build- and run-time dependencies:
    brew install mesa meson ninja sdl2
    brew install --cask chromium
    
  2. Clone this repository
  3. Create a game subdirectory below the repository, and install your copy of the game as game/sundog.st
  4. Build from source:
    meson setup --buildtype release build -Dbuiltin_image=true
    ninja -C build
    
  5. Install the built binary somewhere not in the PATH (see below), e.g.
    mkdir /usr/local/lib/sundog
    cp build/src/sundog /usr/local/lib/sundog/
    
  6. Create a shell script /usr/local/bin/sundog that reads
    export SDL_VIDEO_EGL_DRIVER="/Applications/Chromium.app/Contents/Frameworks/Chromium Framework.framework/Versions/Current/Libraries/libEGL.dylib"
    exec /usr/local/lib/sundog/sundog "$@"
    
  7. Run Chromium by hand once, so as to validate the “unknown developer” warning — If you don't, the next step will complain (because the copies of libEGL.dylib and libGLESv2.dylib that sundog attempts to dynamically load, must be whitelisted by the OS before running)
  8. Run sundog from the command line.

Build settings

The following settings can be set with -Doption=value on the meson command line, or through meson configure:

  Project options                                Default Value                                    Possible Values                                  Description
  -----------------                              -------------                                    ---------------                                  -----------
  builtin_image                                  false                                            [true, false]                                    Use built-in disk image (must be in game/sundog.st)
  debug_ui                                       false                                            [true, false]                                    Enable debug user interface
  game_cheats                                    false                                            [true, false]                                    Enable cheats
  psys_debugger                                  false                                            [true, false]                                    Enable P-system command line debugger

Other platforms

People have built this software for other platforms. It should be pretty straightforward, as we've tried hard to make the source and build system as compatible as possible. Also, SDL2 and support for OpenGL ES 2.0+ (especially when coupled with ANGLE) is widely available.

The CI checks run on Linux (gcc), MacOS (clang) and Windows (MSVC). However, no instructions have been contributed for manual builds on these platforms.

Invocation

The game can be started using the command line:

build/src/sundog[.exe] [<image.st>]

Where <image.st> is the Sundog disk image to use. If none is provided, it will look for sundog.st in the same directory as the program. If it isn't found there, the game will fail to start.

Other options can be provided:

  • --fullscreen: Make window initially fullscreen.
  • --right-click-emulation: Dedicate the top right corner of the screen to right-click emulation (e.g. for tablets)
  • --no-right-click-emulation: Disable right-click emulation in the top right corner
  • --renderer <renderer>: Set renderer to use:
    • basic is the default, which applies straightforward nearest pixel filtering to scale the image.
    • hq4x is a higher quality pixel art scaler that takes neighbour pixels into account. This is a more expensive algorithm that requires a GPU capable of OpenGL ES 3.0.
    • hqish is another higher quality pixel art scaler. It's different than hq4x in that it doesn't hardcode a scale factor but computes everything on the fly. This may look better for larger resolutions. YMMV.
  • --help: Display a help message and exit.

Playing

After starting the program the game will immediately start.

Lots of hints for playing the game, as well as the original manual can be found on the excellent Sundog information page.

Key shortcuts

The game is controlled with the mouse only. There are however some key shortcuts for the interpreter:

  • Pause/unpause game
  • s Save state to sundog.sav in current directory.
  • l Load state from sundog.sav in current directory.

Some other shortcuts are debugging related, see debugging.md.

Status

What works?

  • Loading screen graphics, palette effects.
  • Starting a new game.
  • Right-click popup in-game.
  • Walking around the ship and in buildings.
  • Liftoff / Landing.
  • Sublight flight.
  • Warp (with fancy effects).
  • Loading / reading save states (l and s respectively).
  • Ground combat.
  • Space combat.
  • Sound effects.
  • Touch screen support: a small area in the top-right of the screen has been designated as "cancel area" and will emulate a right-mouse click when touched. This can be disabled by passing --no-right-click-emulation on the command line.

Is it fully playable? Yes, I played it for quite a bit. All the critical things have been implemented, Though I cannot guarantee that there aren't any bugs left. If so, please report them through the issue tracker, along with a saved state if possible.

P-system

Sundog uses version IV.2.1 R3.4 of the p-system. This is a version of the p-system developed commercially by Softech. I looked at using ucsd-psystem-vm, however this implements version II.0 which is significantly different. As far as I know this is the only open source, publicly available p-system IV implementation. It is fairly independent of the game, so if it is useful for anything else it could be factored out to a library. Code for the p-system interpreter is in src/psys.

The p-system has a custom disk layout (this is why on the Atari ST the disk looks like it has only a small .prg and the rest of the disk is empty). This layout is very basic: it supports only contiguous files, and there is only the top-level directory.

P-code is stored in code files, which in turn are organized into segments. Segments are self-contained and can be compared to "units" in later Pascal variants. These in turn contain one or multiple procedures.

At bootstrap time the interpreter seeks into a code archive SYSTEM.PASCAL, loads the segment USERPROG, and starts interpreting at procedure 1 of that segment. From there the p-system takes care of the rest of initialization, eventually executing SYSTEM.STARTUP. This is the game, in this case.

In modern terms the P-system is comparable to the Java Runtime Environment, but more low-level. Some "advanced" features (for the time) that are supported:

  • OS, architecture, endian-independent bytecode.

  • Tasks (multi-tasking), synchronized using semaphores.

  • External events (user input, timer interrupts) can signal semaphores.

  • Paging ("swapping") of code. Segments are loaded when accessed, causing a segment fault to occur. When there is memory pressure, least recently used code segments are discarded, and will be reloaded when used again.

  • Run-time error handling.

  • Dynamic memory management (the heap).

It most notably does NOT do:

  • Security and sandboxing. Everything can read and write everywhere.

  • Address more than 64KiB (or 128KiB on word-addressed architectures) of data memory. It does however use "code pools" to be able to store more code and string constants.

The game includes a rudimentary debugger (use d key to start it) which can be used to poke around in the internals of the p-machine.

The best overview of the internals of the p-system version IV is the "p-System Software Reference Library: Internal Architecture", which can be found on bitsavers.

Retrospect

In retrospect we could have gotten away with emulating way less of the actual p-system, if we'd emulated at the run-time level instead of the OS level. The game doesn't use any of the OS functionality, besides one background task. The paging was not required even with the 1MB of memory of an Atari ST. Most game data is static, it hardly uses dynamic memory management.

So we could do away with SofTech's SYSTEM.PASCAL runtime and replace it with a minimal stub in C. Run the game itself only.

That said, I didn't have enough knowledge about the whole thing when I started this, and besides, it's kind of cool how this project is as much of a toy operating system as a game. Unless the PASCAL source code of the original game happens to become open source (:smile:) there's little reason to do otherwise.

Debug UI

Debug UI

A debug UI can be compiled in to aid with debugging and reverse engineering. For more information, see debugging.md.

Credits

Authors:

  • Wladimir J. van der Laan

Contributions in the form of github pull requests are very welcome.

Special thanks to:

  • Bitsavers
  • The former UCSD pascal group on Yahoo
  • ocornut for the "dear imgui" GUI system used for debug GUI
  • Mitsutaka Okazaki for emu2149
  • Of course late FTL software: Bruce Webster, Doug Bell, Wayne Holder, Mike Newton, Andy Jaros for making SunDog in the first place.

License

This software is provided under the MIT license.

sundog's People

Contributors

laanwj avatar miniupnp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sundog's Issues

Settings UI

For windowed operating systems it would be nice to have a little GUI where it's possible to configure the renderer, where to find the disk image (though, #24 may be better for that), and so forth. A bit like what ScummVM has. I don't particularly want a dependency on any widget toolkit like gtk or qt, though. So I'm not sure.
(one possibility is to use imgui here as we already use it for the optional debug UI)

This also needs the functionality to store persistent settings in an ini file or such.

todo: linux disto inclusion, appimage?

It may make sense to see if we can get packages for various linux distros, or something cross-distro like appimage.

Edit: the latter should be easy now that the application only depends on SDL2 directly.

C99 code : -std=c99 should be specified in CFLAGS

see :

gcc -Werror=implicit-function-declaration -Wmissing-declarations -Wall -Wextra -Wno-unused-parameter -Og -Wall -ggdb3 -g3 -I. -DFLIP_ENDIAN_HACK -DPSYS_DEBUGGER -DGAME_CHEATS -DENABLE_DEBUGUI -I/usr/include/SDL2 -D_REENTRANT  -Wmissing-prototypes   -c -o psys/psys_debug.o psys/psys_debug.c
psys/psys_debug.c: In function ‘psys_print_info’:
psys/psys_debug.c:176:13: error: ‘for’ loop initial declarations are only allowed in C99 mode
             for (int x = 0; x < op->num_out; ++x) {
             ^
psys/psys_debug.c:176:13: note: use option -std=c99 or -std=gnu99 to compile your code

https://travis-ci.org/miniupnp/sundog/builds/527263027

But maybe you prefer to change the code to make it C90 compliant ?

Creating a new character is very fiddly

In the librarian, when creating a new character, entering the name and clicking the "+" to confirm, it tends to automatically click the "No" button in the screen afterwards, bringing you back to the name entering screen.
It's possible to work around this by clicking in exactly the right place, at the bottom of the "+" button where it doesn't intersect the "No" button. This is kind of fiddly though.

I suspect the reason for this bug is the speed of the emulation. On an Atari ST by the time the next screen is drawn, the user will have released the mouse button. It may be possible to artificially insert a delay somewhere.

Look for disk image in directory of executable

At least on Windows, it's cumbersome to pass command line parameters. It would be nice to be able to drop it in the same directory as the .exe an its DLLs, and just work.

I'd propose looking for (say) sundog.st in SDL_GetBasePath() when no image filename is passed explicitly.

In Linux and MacOS this is likely not too useful. On Linux a automatic mechanism for locating game data usually works relative to an install paths that is built into the executable (something like /usr/share/games/sundog), or maybe there's some XDG convention.

Can we make it work on MacOS?

Thank you for your efforts.

I am trying to get this working on MacOS. I noticed that it needs EGL to run. I found the ANGLE EGL project, but can't figure out how to make them work together.

I built the Angle project and then ran the sundog you made that I also had built and sundog is reporting it can't create the EGL window.

Can you point out in your project where the compiling and linking to EGL would be? I think I need to put it to the Angle project's libraries.

An official release tag?

Hi Laanwj,

I stumbled across your lovely port of Sundog today after doing some research on the game, and would absolutely love for it to be included in my favored Linux distro, Solus, so that others may enjoy this unique title (maybe even becoming excited enough to consider expanding upon your efforts?).

However, to be eligible for inclusion into the Solus repo's, a program generally must have an official 'stable' release of some sort.

Would it be possible to tag the latest build here on github as a 1.0 release? I understand there's still a few non-critical things missing from the game, but seeing as it's still fully working & playable, it should be eligible for inclusion were it tagged as such.

Thank you for your time and consideration, and for porting this hidden gem.
Cheers! :)

Competely Different Graphics Layer

I would like to port this to an entirely different graphics system if that is possible. Can you give me some tips on where I can insert my own graphics later? I notice in the code it seems to get to the pixel rendering layer and I can do that in the system I want to port to. The question is can I completely remove SDL2 and EGL? If so, where is that "seem" or Interface best replaced?

I want to extract all the game's Atari ST art assets.

I want attempt to recreate parts of the original Sundog game for a fun. I was trying to extract the original art assets via screen shots and then recolor them, but I realized that it might be easier see if there was a way to just extract the assets from the original game. Is an easy way to do this?

Unknown Op Code

I was able to find a SDL2 example project for iOS. I imported your project into that project and fixed up some compiler errors.

I then loaded it up and it seems to get started ok, but then encounters an unknown Op code and has a fatal error.

Here is the debug output:

psys_bootstrap: 1024 entries in global directory
Found SYSTEM.PASCAL at offset 380400
Found USERPROG at offset 0x380400, size 0x00000, globals_size 0x0000
Needs byteswap
Initial IPC at 0xf3ec:0x01:0x0002
Initial TIB at 0x006e
Initial EVEC at 0xf3b8
Initial EREC at 0xf3be
Initial SIB at 0xf3c8
Initial global MSCW at 0x008a
Initial local MSCW at 0xf3ae
SYSCOM at 0x0000
EXTM at 0x0060
Execution error 11 (fatal)
Traceback [tib=006e sp=efa4]
:0x01:0207 mp=0xf3ae base=0x008a erec=0xf3be
:0x01:0002 mp=0x008a base=0x008a erec=0xf3be

That is actually kind of exciting that it got that far at least. I am using a disc image from here:

https://www.oldgames.sk/en/game/sundog-frozen-legacy/download/8755/

The Execution error 11 seems to be triggered because the app is encountering an op code of 64 decimal or 0x40 hex. If I look that up in the header it is PSOP_UND40.

Any thoughts on why I might get that code?

The other thing that is interesting that you may not be able to help with is that on line 62 of the psys_bootstrap.c file I get a memory exception if I just let the app run.

When I went to debug this I put a breakpoint on that line. If I stop on that line with the breakpoint and then hit run or single step it works fine.

Is there some kind of threading thing or startup timing thing that would cause that to not work when it just runs versus stopping on that line and continuing?

I know this is an old repo, but am hoping maybe you can help me get this working. I am not interested in releasing it without permission or anything. I mainly just want to play it myself on my iPhone.

Thanks!

Better handling of resources

Currently, (optional) sounds and intro graphics are looked for in subdirectories of the current directory. This is hardcoded, and can be inconvenient for some forms of installation. It would be better to either handle installation paths, or even link all the data into the binary (it's not that much).

Thanks!!

Thanks for linking to my Sundog Info site (lukin.com/sundog/) - I really appreciate it!

I am going to try to get this up and running on my Mac and plan on updating my sites emulation page. I will be sure to add your project to it (if that is ok with you?).

Windows instructions

After having converted the build system to meson, and reducing the build-time dependencies to just SDL2 (for the non-debugger build), it should be more straightforward to do a windows build.

I don't know windows development myself, so could use some help here.

I'm impressed

Perhaps you recognize my name. I have an idea for how this project might reach a wider audience. If interested, please contact me at:

questions4wayne at gmail dot com

Wayne Holder

Some of the sound effects are broken

While sound playback is implemented now, some of the .ogg converted from original ST dosound format are silent, or otherwise not correct.

There is probably some bug in the dosound tool used for conversion.

According to Wayne Holder:

The sounds that seem off, or silent seems to be ones where I would expect the sound chip to be using some type of white noise in the effect. Perhaps this capability is not supported in emu2149.

Go back to msleep

Recently I implemented my own util_usleep function as it seems fine enough precision, but usleep is deprecated in POSIX. In POSIX it can be easily implemented in terms of nanosleep.

However, usleep implementation on Windows is absolutely bonkers. I'm not sure it actually works that well.

We don't really need sub-millisecond precision waiting. Waiting is used for:

  • Input delays (to compensate for the speed of the emulation). These are larger delays, in terms of milliseconds.
  • Wowzo animation, to make the speed of the hyperspace animation approximate the Atari ST speed. These are smaller delays (in terms of 68000 DIV instructions). it's pointless to wait less than a frame. It would be better solved by accumulating delays and waiting a frame when needed. Or some fraction of a frame.

todo: build system

It would be great to have some actual build system like cmake or meson (the latter seems to be the preferred choice nowadays), instead of the hack job makefile we're currently using. This would make it possible to have build-time configuration settings, and make it easier to build for different platforms and architectures.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.