If you'd like to support our preservation efforts (and this wasn't cheap), please consider donating or supporting us on Patreon. Thank you!
Notes:The Adventures of Captain Comic (DOS)
This page contains notes for the game The Adventures of Captain Comic (DOS).
Contents
Revisions
The Internet Archive has all five revisions under the item TheAdventuresOfCaptainComic:
It also has three other versions:
- swh11988 (file_id.diz labels it "Hacked/grafitti version 1")
- swh21988 (file_id.diz labels it "Hacked/grafitti version 2")
- R4a1sw1989 (file_id.diz labels it "Alternate version 1")
File Formats
Malvineous has documented the file formats here.
Executable Packing
In every revision, COMIC.EXE is packed with EXEPACK. Revision 1 uses an earlier version of EXEPACK that not all unpackers can handle. Try these ones:
R1swh21988 (a hacked version) doesn't have COMIC.EXE but rather MENU.EXE, and the EXEPACK layer appears to be wrapped in another layer that adds an advertisement for "Red Point".
Sound Effects
The format of a sound effect is an array of
struct {
uint16_t freq_divider;
uint16_t duration;
};
The 16-bit values are stored little-endian. Each freq_divider divides the Programmable Interval Timer base frequency of 1193182 Hz. For example, a freq_divider of 1c3f would result in an output frequency of 1193182 / 0x1c3f ≈ 165 Hz. The special freq_divider value 0028 indicates a rest. duration is in number of beats; each beat is about 55 ms (one tick of the 18.2 Hz IRQ 0 timer). The end of the sound is marked by a freq_divider of 0000.
Table of offsets to sound effects in the unpacked executable. Assumes that the unpacked executable has an EXE header of 512 bytes. Changed sounds are highlighted.
| R1sw1988 | R1swh11988 | R2sw1988 | R3sw1989 | R4a1sw1989 | R4sw1989 | R5sw1991 | |
|---|---|---|---|---|---|---|---|
| title | 2521 | 2521 | 25a2 | 25d2 | 27a2 | 27a2 | 29c4 |
| start | 2665 | 2665 | 2bc0 | 2bf2 | 2daa | 2d9e | |
| door | eda9 | eda9 | f309 | f339 | f4f9 | f4e9 | fc29 |
| player death | edd1 | edd1 | f331 | f361 | f521 | f511 | fc51 |
| teleport | edf9 | edf9 | f359 | f389 | f549 | f539 | fc79 |
| bonus | ee19 | ee19 | f379 | f3a9 | f569 | f559 | fc99 |
| materialize | ee25 | ee25 | f385 | f3b5 | f575 | f565 | fca5 |
| game over | ee85 | ee85 | f3e5 | f415 | f5d5 | f5c5 | fd05 |
| screen transition | eede | eede | f43e | f46f | f62f | f61f | fd3f |
| lost life | eefe | eefe | f45e | f48f | f64f | f63f | fd5f |
| shoot | ef4e | ef4e | f4ae | f4de | f69e | f68e | fdae |
| enemy death | ef5a | ef5a | f4ba | f4ea | f6aa | f69a | fdba |
| player damaged | ef71 | ef71 | f4d1 | f501 | f6c1 | f6b1 | fdd1 |
| item get | ef81 | ef81 | f4e1 | f511 | f6d1 | f6c1 | fde1 |
| extra life | ef95 | ef95 | f4f5 | f525 | f6e5 | f6d5 | fdf5 |
References for Code Changes
R3 Esc
| Revision 2 @ 76 | Revision 3 @ 76 |
|---|---|
cd16 int 0x16 ; get keystroke; al=ASCII code
3c6b cmp al, 0x6b ; 'k'
7407 je setup_keyboard
3c4b cmp al, 0x4b ; 'K'
7403 je setup_keyboard
e95001 jmp game_start
|
cd16 int 0x16 ; get keystroke; al=ASCII code
3c6b cmp al, 0x6b ; 'k'
740e je setup_keyboard
3c4b cmp al, 0x4b ; 'K'
740a je setup_keyboard
3c1b cmp al, 0x1b ; Esc
7503 jne any_other_key
e95203 jmp terminate_program
any_other_key:
e95401 jmp game_start
|
R3 Del
| Revision 2 @ 1b6 | Revision 3 @ 1a0 |
|---|---|
await_keypress:
; [...]
; bx is scancode
4b dec bx ; scancode == 0x1 (Esc)?
74c5 je await_keypress
83fb51 cmp bx, 0x51 ; scancode > 0x52 (Ins)?
7fc0 jg await_keypress
; assign scancode to action
|
await_keypress:
; [...]
; bx is scancode
4b dec bx
74d1 je await_keypress ; scancode == 0x1 (Esc)?
83fb52 cmp bx, 0x52
7fcc jg await_keypress ; scancode > 0x53 (Del)?
; assign scancode to action
|
R3 Keyboard Buffer
| Revision 2 @ 2b4 | Revision 3 @ 1d1 |
|---|---|
; 0040:1a is pointer to beginning of the buffer of pending keystrokes
; 0040:1c is pointer to end
268a0e1a04 mov cl, byte es:[0x41a]
26880e1c04 mov byte es:[0x41c], cl ; set end = beginning
|
; 0040:1a is pointer to beginning of the buffer of pending keystrokes
; 0040:1c is pointer to end
fa cli ; disable interrupts
268a0e1a04 mov cl, byte es:[0x41a]
26880e1c04 mov byte es:[0x41c], cl ; set end = beginning
fb sti ; enable interrupts
|