Skip to content

About

Playable full Alpha Waves (Infogrames, 1990) for dosbox-staging — CODE: copy-protection baked-in bypass of PROGS.CC1

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Alpha Waves — playable full version in DOSBox

Alpha Waves (Infogrames, 1990 — credited as one of the first 3D platformers) ships with a CODE: copy-protection prompt tied to a physical code wheel. The game also includes a runtime crack (Alpha.com) that hooks DOS interrupts to patch the protection check in memory. Under dosbox-staging that hook doesn't fire reliably, so the crack wrapper does nothing: you get the CODE: prompt, type anything, and get kicked back to DOS with no music and no gameplay.

This repo bakes the exact same byte patch Alpha.com would write at runtime directly into PROGS.CC1, so the protection check is neutralized before the game ever runs. The result: the full 256-room game plays with AdLib FM music under DOSBox, with no CODE: prompt to deal with.

Patch flow

Play it

Prerequisites:

  • dosbox-staging (sudo apt install dosbox-staging on Debian/Ubuntu)
  • A Linux machine; on WSL the launcher uses /mnt/wslg/PulseServer for audio
./play.sh

At the language menu press F2 for English (or F1 French / F3 German). There is no CODE: prompt — the game goes straight into its intro, menu, and gameplay.

DOSBox settings live in alphawaves.conf: SVGA S3, fixed 3000 cycles, SB16 with OPL2 (nuked emulator), PC speaker and Tandy enabled. Those match what actual period AdLib hardware sounds like and don't starve the game's timing loops.

How the patch works

The protection check

Each language variant of the game executable (PROGS.CC1 blocks 3 = German, 4 = English, 5 = French) contains this validation function:

; ... hash the user's typed code into AH ...
    inc   dx
    cmp   ah, cl             ; stage 1: compare against CL
    jne   +0Fh               ; fail → skip to stage 2
    ; ... more hash work ...
    inc   dx
    cmp   ah, ch             ; stage 2: compare against CH   <-- signature 3A E5 75 0C
    jne   +0Ch               ; fail → return AX = 0xFFFF
    mov   bx, 21B1h          ; success path
    mov   ax, [cs:di]
    shr   ax, 1
    inc   dx
    shl   word [cs:bx], 1
    add   [cs:di], ax
    mov   ax, dx             ; return AX = DX (4 on full success)
    pop   di / si / ds / es / bp
    ret

The caller treats AX == 4 as "code accepted".

What Alpha.com writes at runtime

Alpha.com scans segment 0x5000 for the signature 3A E5 75 0C and, when it finds it, writes two patches:

Offset Before After Meaning
[SI-0x2D] 75 0F 90 90 NOP out the stage-1 jne
[SI] 3A E5 75 0C BA 03 00 90 replace cmp/jne with mov dx,3; nop

After the patches the function always falls through to the success path, hits inc dx once more (→ dx = 4), and returns success regardless of what you typed.

What this repo does differently

Instead of relying on Alpha.com's TSR hook (which is unreliable under DOSBox), patch_progs.py bakes those exact 6 bytes into PROGS.CC1 itself. The signature lives in all three language variants, so all three get patched.

The CC1 container format looks like:

outer:   uint16_be count
         uint32_be offsets[count]
block:   uint32_be packed_size
         uint32_be unpacked_size
         packed_size bytes of payload
payload: a chain of BPE-compressed sub-blocks
sub-block:
         uint8   psz     ; BPE pair-table size, or 0 for a raw sub-block
         uint8   flag    ; 1 = more sub-blocks, 0 = last
         uint16  dlen    ; payload length (LE)
         if psz != 0:
             psz bytes table2, psz bytes table0, psz bytes table1, dlen bytes compressed data
         else:
             dlen bytes of raw uncompressed data

In every language block, the signature lives inside sub-block 6 (the BPE-compressed sub-block covering uncompressed offsets [10963..12754) in block 4, similar ranges in blocks 3 and 5). The patcher:

  1. BPE-decompresses sub-block 6 to recover 1791 raw uncompressed bytes.
  2. Applies the two byte writes (same ones Alpha.com would write).
  3. Re-emits sub-block 6 as a raw sub-block (psz = 0) — no need to re-encode BPE for such a small blob.
  4. Bumps the block's packed_size by ~329 bytes and adjusts the outer offset table so blocks after it still line up.

A failed earlier approach was to rewrite block 4's entire payload as a small number of raw sub-blocks. uncompress_cc accepts that shape fine — but ALPHA_E.COM's own loader does not, and the game hangs on a black screen. Keeping the original sub-block topology and replacing only the one sub-block that matters avoids that.

Regenerating the patched PROGS.CC1

If you want to re-apply the patch from a fresh copy of the game:

python3 patch_progs.py path/to/original/PROGS.CC1 game/PROGS.CC1

The script prints which blocks were patched — expect [3, 4, 5].

Repository layout

alpha_waves/
├── README.md                 this file
├── patch_progs.py            the patcher (no deps, pure stdlib)
├── play.sh                   dosbox-staging launcher
├── alphawaves.conf           DOSBox config (SVGA S3, OPL2, 3000 cycles)
├── game/                     the game files, with PROGS.CC1 already patched
└── docs/
    └── patch_flow.jpg        flow diagram

Verifying the patch

An easy sanity check with the original unpatched PROGS.CC1: type 333 at the CODE: prompt. It's rejected and the game exits to DOS. With the patched PROGS.CC1, the same input passes — because the validation function now always returns success. That flip is the entire bypass.

Confirmed working on 2026-04-17 under dosbox-staging on WSL2.

Credits and acknowledgements

  • Original game: Alpha Waves, designed by Christophe de Dinechin, published by Infogrames in 1990.
  • CC1 format reverse-engineering reference: the uncompress_cc tool from the alpha_waves_loader project — used here to validate that the patched PROGS.CC1 round-trips correctly (decompresses back to exactly the original bytes except for the 6 patched bytes in each language block).
  • Alpha.com runtime crack (unattributed, circa 90s) — the source of the exact byte patches baked in here.

About

Playable full Alpha Waves (Infogrames, 1990) for dosbox-staging — CODE: copy-protection baked-in bypass of PROGS.CC1

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages