Skip to content

rsquared68/schreckenstein64

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Schreckenstein-64

This project is a study of Peter Finzel’s superb two-player head-to-head jump and run dungeon explorer for the Atari line of 8-bit home computers and my attempt to accurately port it to the Commodore 64. I discovered this game when a friend gifted me an 800XL and I had a blast playing it. I had been thinking of trying a C64 project to build on what little 6510 coding skills I had remaining since the 1980s, and the complexity of the display of the original game seemed like it would be really challenging for me to implement. However, with all that had been learned by democoders since I last touched a C64 it seemed like it was maybe possible for me to do.

Eventually I got something working. It is a little slower than the original because of the CPU clock difference, the lack of CPU-independent display list processing in the C64, and the fact that screen memory occurs in fixed blocks within the VIC bank and you can’t just point to an arbitrary memory location as the start of a screen like you can with the Atari. Therefore the CPU is doing a lot of heavy lifting with raster interrupts not required on the Atari. This is my first project of this type other than a few small and mostly unimpressive demoparts, so there were quite a few weeks where I thought it might actually be impossible. But with the magic of memcopy speedcode generated realtime each frame to permit absolute loads and a few other tricks, I managed to be able to draw all of the graphical elements. After convincing myself of the proof of concept, I started to disassemble and reverse-engineer the Homesoft “[a2]” crack of the original game to uncover and extract the game engine for integration with my graphical kernel. That worked, so I somewhat hastily added a sound engine and option/hi-score/victory screen code to arrive at the RC1 release. In addition to its graphics, Peter’s original Atari game is remarkable for the variety and detail of the 32 different sound effects, which usually use 3 but sometimes 4 POKEY audio channels. The SID only has three channels, has complicated re-gating “requirements” (due to the envelope bug), and I need to sparingly use channel 3 because it is also my random number generator. This causes some sounds to get blocked/overwritten in the RC1 release. For the "100%" release I completely re-did the approach to sound arbitration so now >95% of the triggered sounds actually play, though some are slightly delayed due to a queue-based approach. I also cleaned a few things up and sped up the loading by exomizing everything but the launcher.

Special thanks are due to Peter Finzel who graciously permitted me open release of my disassembly and reverse-engineering of the binary included this repository. Peter is still coding after so many years and it was great to have a short exchange of messages with him. He mentioned that part of the original was written the Atari language Action! and you may detect a certain kind of repeating code template in the source if you examine it. He also mention that he used his own Action! runtime library for some of the implementation; so this code represents quite a view into Atari development history for that time period.

Architectural discussion

Drawing the screen with 3 raster splits across two views with independent 8-way fine scrolling is the heart of this code--the C64's CPU doing most of the work done by the ANTIC in the Atari version. Most all of the time between vertical blanks is spent in a raster interrupt handler, with a few breaks to jump out and execute the original game engine to move the enemies and handle the other game mechanics. There is not a single large enough time block between raster interrupts to handle any one of the four memory-copy instances needed to update the viewports without immediate-mode speedcode. These four memory-copy instances are the two which implement the coarse-scrolling of the viewports, and the two which move the opposing player's image in a particular player's view. The player is represented by a sprite in his own view, but the opposing player in the same view is copied into a vertical strip of sprites similar to the way player/missile graphics work on the Atari. This was an architectural decision by me to keep the VIC-II sprite DMA timing constant near the raster splits forming the statusbars. The timing was challenging enough with badlines constantly moving independently in both viewports, and it was easy enough to implement the priority or layering beneath the statusbars. In retrospect the game would be faster if I only used one sprite and moved it in the viewport, doing the memory-copy only at the vertical edges--I think this is possible. The speedcode for the four memory moves is generated wherever I have CPU cycle delays (waits) between raster-timing critical events like multplexing sprites, switching screens/charsets/MCM etc. The viewport coarse memory copies alternate, with each player's view updated on odd/even frames, though hardware fine scrolling updates every frame. The sound effect players are similary stuffed into any cycles I had remaining in wait-for-raster-position delay loops. Because these are all constant cycle-count delays, all the branch paths are equal-time. In RC1 I compensated for extra page-crossing delays in indexed addressing with CIA timer-based stabilizers to keep the different accesses in time with the raster, but in the "100%" release I switched to a direct calculation of the different delays which is more easily tuned over a wider range.

The memory allocation is based on the "put it where you can" philosophy, primarly because the VIC-II can only access one 16K bank of memory at a time (unlike the ANTIC). Because of all the animation, there are 5 character tilesets and 64 sprite images, plus 8 sprite images for the statusbars, plus two screens for the graphics and text lines. So all of VIC bank 1 is completely stuffed and some of the graphic data needs to go into portions of the screens which are never actually displayed due to the raster splits. Beyond that the rest of the code fits reasonably comfortably in the C64 without too many contortions.

The remainder of the architecture is fairly organic and probably far off optimal. Originally I wanted to do the screen only as just a graphic tech demo exercise for myself. Once I got it running with some of the Atari game-engine logic I sort of slapped on a loader and whatever was necessary to make it playable. The intro/option screen was incorporated similarly, as was sound. I eventually greatly improved the sound for the "100%" release but the rest of the structure is not particulary sane. However the game plays well and I'm fairly happy with it :-)

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published