Skip to content

C64 Vertical Parallax in Horizontal Scrollers

Implementing vertical parallax motion within horizontally-scrolling multi-layer landscapes represents a previously unrealized technique on the Commodore 64. This documentation covers the hybrid implementation approach developed to achieve the effect.

Traditional C64 parallax scrollers employ horizontal motion only—background layers move left and right at different speeds to create depth perception. Adding vertical parallax (layers rising and falling as the view moves) enhances the dimensional effect substantially, creating more convincing landscape illusions. However, the VIC-II’s vertical scroll capabilities prove far more constrained than horizontal scrolling, requiring creative combination of multiple techniques.

This article documents the first known implementation of vertical parallax within a horizontally-scrolling game engine on the C64. The solution required combining four distinct approaches, each addressing different screen regions and movement requirements.

Approach Development

Initial implementation targeted the VIC-II’s $D011 register for hardware vertical scrolling. While effective for foreground elements, upper background layers proved problematic. The technique demanded precise interrupt coordination to preserve open border regions while constraining vertical scroll range to 3-4 pixels before triggering system instability.

The $D011 approach works by modifying the 3-bit vertical scroll value (bits 0-2) mid-frame at different raster positions. Each layer receives its own scroll value, creating apparent vertical displacement between layers. In theory, this provides hardware-accelerated vertical parallax. In practice, interactions with bad-line timing, border opening, and sprite multiplexing created severe constraints.

The instability arose from timing conflicts between $D011 manipulation and the VIC-II’s internal state machine. Modifying vertical scroll during specific cycle positions within the raster line caused the VIC-II to enter undefined states, producing screen corruption or complete lockup. Safe timing windows proved narrower than initially expected, limiting practical vertical travel to few pixels.

Final implementation combines four distinct techniques rather than relying on hardware scrolling exclusively.

Combined Methodologies

1. Register-Based Scrolling ($D011)

The distant mountain layer employs direct register manipulation, executed within the initial raster handler positioned above visible screen boundaries.

This technique applies where constraints are least severe—the topmost screen region, above sprite activity and before complex layer interactions. The raster handler modifies $D011’s scroll bits during the vertical blanking period or early visible frame, establishing the mountain layer’s vertical offset before subsequent layers complicate timing.

The implementation calculates vertical offset from player position, applying a fractional relationship (distant layers move less than near layers). The mountain layer might shift 1 pixel for every 8 pixels of player vertical movement, creating convincing distance-based motion parallax.

2. Character Definition Cycling

Distant vegetation layers cycle through vertically-offset character definitions, transitioning rapidly between pre-drawn graphics sets during non-critical processing windows.

Rather than moving the layer through register manipulation, this approach modifies what the layer displays. Pre-computed character sets contain the same graphics shifted vertically by 1-pixel increments. Cycling through these sets produces apparent vertical movement without any VIC-II scroll register changes.

The character cycling approach consumes memory (8 character sets for 8 vertical positions requires 16KB if complete sets are stored) but operates with minimal CPU overhead during runtime. The actual switch requires only modifying the character base address in $D018—a single register write that can occur during any timing window.

3. Character Set Switching

Intermediate foothills layers require complete character bank transitions, necessitated by insufficient character space for all scroll-phase variations within single banks.

This extends the character cycling concept to handle layers requiring more than one character set’s worth of graphics. The foothills graphics include terrain details, vegetation, and color variations that consume the full 256-character capacity. Vertical offset variations for these graphics reside in separate banks, switching during appropriate raster positions.

Bank switching adds complexity: the switch must occur at layer boundaries (when the raster passes from one layer to another) and must complete before the VIC-II begins fetching data for the new layer. Interrupt timing for these switches requires sub-scanline precision.

4. Flexible Line Distance (FLD)

This demoscene-derived technique delays VIC-II rendering across targeted scanline ranges, enabling smoother vertical transitions across mountain and foothills layers simultaneously.

FLD works by manipulating the $D011 register to delay bad-line processing. Normally, the VIC-II fetches new character data every 8 scanlines (on “bad lines”). FLD suppresses this fetching by keeping the vertical scroll counter from matching the bad-line trigger condition. The result: character rows stretch vertically, appearing to shift position without memory manipulation.

Applied strategically at layer boundaries, FLD smooths transitions that would otherwise appear stepped. The mountain and foothills layers can appear to slide past each other continuously rather than jumping in 8-pixel increments. The technique requires precise interrupt timing but provides visual refinement that other approaches cannot achieve.

Color Preservation

Alternating Line Method (ALM) color blending introduced visual corruption during vertical scrolling. Resolution required character bank switching synchronized with vertical pixel displacement to maintain consistent color rendering.

The ALM color technique alternates pixel colors between adjacent scanlines, relying on CRT color bleeding to produce perceived intermediate hues. When vertical scrolling shifts layers by odd pixel counts, the alternating pattern becomes misaligned—colors that should blend instead display as visible stripes.

The solution pre-computes character sets for both even and odd vertical positions, with ALM patterns adjusted to maintain correct blending regardless of vertical offset. When vertical position changes from even to odd (or vice versa), the engine switches to the correspondingly adjusted character set. This doubles the required character data but preserves color quality throughout vertical motion.

Engine Architecture

The complete interrupt framework now coordinates nine distinct handler routines:

  • Sprite multiplexing management
  • Animation sequencing
  • Collision evaluation
  • Border state control
  • Vertical parallax coordination

The nine handlers must execute in precise sequence, each completing before its designated raster position. The scheduler maintains a queue of pending operations, distributing them across available handlers based on current frame requirements. Some operations can defer to the next frame if timing budgets exhaust; others (visible display effects) must complete within strict windows.

Handler interaction creates the primary complexity. Sprite multiplexing modifies $D010-$D017 (sprite position/control registers); vertical parallax modifies $D011 (control/scroll register) and $D018 (character base); both require precise timing that can conflict if handlers execute too slowly. The architecture minimizes handler duration and carefully sequences operations to prevent conflicts.

Foreground vertical travel range expanded from 8 to 16 raster lines following implementation refinements.

The initial 8-line limit resulted from conservative timing margins. As handler code optimized and timing became better understood, wider safe windows emerged. The 16-line range provides more dramatic vertical motion—noticeable landscape undulation during player movement—while remaining within stable operating parameters.

Technical Achievement

This represents the sole documented implementation of layered vertical parallax within horizontally-scrolling environments on Commodore 64 hardware. The technique enhances dimensional perception within scrolling gameplay scenarios.

The visual impact proves substantial. Where conventional horizontal-only parallax creates left-right depth, adding vertical motion creates complete dimensional illusion. Landscapes appear to exist in three-dimensional space rather than as flat layered planes. Player movement feels more connected to the environment when both horizontal and vertical parallax respond to position changes.

The implementation complexity reflects the technique’s novelty. Combining four distinct approaches, coordinating nine interrupt handlers, and managing character set memory for multiple vertical positions required substantial development iteration. The resulting system operates within acceptable performance bounds but represents the practical limit of what the combined techniques can achieve.

Applicability

The vertical parallax techniques documented here apply primarily to specific visual designs—layered mountain landscapes with defined horizon bands. Other visual styles may not benefit proportionally, and the implementation complexity may exceed practical value for simpler presentations.

Games emphasizing other visual priorities (numerous sprites, complex animation, detailed characters) may find the interrupt handler overhead incompatible with their requirements. The technique suits projects where landscape depth and environmental immersion take design priority.

Related: Product Information

See also: The Wild Wood engine · world-anchored sprites · Deep Winter sprite multiplexing · VSP scrolling analysis