Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Apple Games Disassembly Project: Castle Wolfenstein

583 views
Skip to first unread message

Michael AppleWin Debugger Dev

unread,
Dec 15, 2014, 3:43:31 PM12/15/14
to
"SS"

Those words struck fear and terror in anyone who played Castle Wolfenstein. You had to be on your guard, pardon the pun, as they would appearing out of no where from the last door. After a quick panic, you would come to your senses: Tossing them a pineapple, er, grenade, would even the odds back into your favor.

The text phrase that have would players reaching for the disk drive and yanking the floppy out before the red saving light came on was:

"You're caught!"

As a game player, developer, and designer, I was always curious just _how many_ digitized phrases did Castle Wolfenstein _actually_ have?

Let's find out !

Along the way we'll see where the map is stored too. :-)

= Tools needed =

* AppleWin 1.25 or later
* https://github.com/AppleWin/AppleWin/releases/download/v1.25.0.3/AppleWin1.25.0.3.zip

* Castle Wolfenstein Disk Image
* http://mirrors.apple2.org.za/ftp.apple.asimov.net/images/games/action/wolfenstein/castle_wolfenstein-fixed.dsk


= Instructions =

Full instructions can be found here

* http://mirrors.apple2.org.za/ftp.apple.asimov.net/images/games/action/wolfenstein/wolfenstein.txt

Here is a quick tutorial on the keys used:

Movement:
Q W E
A D
Z X C
S = Stop

Aiming:
I O P
K ;
M , .

L = Shoot gun
T = throw grenade (in dir. gun is pointing)
Space Bar = Search dead bodies, Open Chests, Open doors (to try keys in door)

Tip: Hold down space bar while searching to take half as long searching.

= Playing =

Let's get hacking ...

1. Start AppleWin.exe
2. Click the 3rd button on the right or Press F3, select: "castle_wolfenstein-fixed.dsk", and press Enter
3. Click the 2nd button on the right or Press F2 to boot the Apple //e
4. There is a bug where sometimes the game doesn't boot; you'll see an error message "OVERFLOW". If this happens, just type in the emulator: RUN and press Enter
5. Press Return at the title screen
6. Press K for keyboard
7. Wait for the introduction text to finish
8. Once you are in the prison room, press F7 to enter the debugger

= Getting familiar with AppleWin's Debugger =

In the deubber you can view the graphic pages via typing:

HGR

Press a key, such as space, to return back to the debugger screen.

Most games use page flipping, but some games use the 2nd graphics page for that extra 8K.

HGR2

We can see that doesn't use page flipping. This is why you'll notice "flicker" when you or the guards move.

One of first things I like to do, is to do a quick scan view memory and look for text.

MD1 5E00
DATA

What's this? We can see: "THEY GOT YOU" and "ACHTUNG"

Press Page Down 3 times. we see "HALT"
Press Page Down 4 more times, we see "EEYAGH"

Here is the full list of voices

ASC 5E38:5E48 // ACHTUNG // "Alert"
ASC 6064:6074 // HALT
ASC 624D:625D // EEYAGH // Death Sound
ASC 661C:662C // YIEEE // Death Sound
ASC 6B7D:6B8D // CHWEINHUND // "Pig-Dog!" Mis-spelt: schweinhund
ASC 7029:7039 // SS
ASC 7570:7580 // PHOLGE // Result. Mis-spelt: Folge?
ASC 7806:7816 // KAMERAD // "Comrade"
ASC 7B79:7B89 // WASISTLOS // "What is happening?" German: Was Ist Los
ASC 819E:81AE // FEUER // "Fire!"
ASC 847C:848C // DAPUT // "(t)Here "
ASC 86F8:8708 // UFWIEDERSEN "Until we meet again." Mis-spelt: Auf Wiedersehen

You can use Dict.cc to listen to pronunciations.

* http://www.dict.cc/?s=WAS+IST+LOS


= Map =

I had always been curious how the map was represented and presented.

It turns out CW uses *over-lapping* 5x5 cells!

The draw map tile is at $D1D; Here is the map tile format; the walls are a simple bit-field.

00 = Empty
01 = Left Wall
02 = Right Wall
04 = Top Wall
08 = Bottom Wall
10 = Stairs

The map itself is stored from $4000 .. $4047:

db map_row1 4000:4007
db map_row2 4008:400F
db map_row3 4010:4017
db map_row4 4018:401F
db map_row5 4020:4027
db map_row6 4028:402F
db map_row7 4030:4037
db map_row8 4038:403F
db map_row9 4040:4047

Locked Doors and Guards are stored elsewhere ... unfortunately I haven't been able to spend more time figuring this out where exactly they are.

For some reason the save game saves address from 4004:7DFF (inclusive):

BSAVE CASTLE,A$4004,L$3DFC


= Misc. =

Over in comp.sys.apple2 a few fans have "ported" the game to run under ProDOS! Great job guys!


= CW Symbols =

I don't want to bore you with the details so here is my partial Work-In-Progress CW reverse engineering symbols debugger script. (How was that for a mouthful!)

RUN CW_SMBOLS.AW

Here is reverse engineering symbols

- - - 8< - - -
// ---------------------------
// -- Castle Wolfenstein --
// ---------------------------
// Apple Games Dissassembly Project
// by Michael Pohoreski
// Public Version 1

// Disable Basic Assembly Symbols
SYMBASIC OFF

// Guard Data
db GuardVest 5028
db GuardBullets 5029
db GuardGrenade 502A
db GuardKeys 502B

// Player Data ... also mirrored at 5877 ??
db myBullet 4347
db myGrenade 4348
db myVest 434A
db bHitWall 434C
db bHavePlans 436C

db chest 587A
db chestitem2 5879 // Item type in chest
db chestsec 587b // Time left on chest.
db chestitem1 40A2 // copied to 5879

// Zero Page Pointers
dw Ptr10 10:11
dw Ptr6B 6B:6C
dw Ptr6D 6D:6E
dw Ptr70 70:71
dw Ptr72 72:73

ASC 348:34C // "WOLF
ASC 353:358 // "CASTLE"

sym Escaped = 08A8
sym PutInMap = 1159
sym Main = 119C
ASC 8C0:8CA // BRUN @INIT
ASC 989:998 // "**I/O ERROR**"
sym ClearHGR = 878
sym _printS = AFA // bottom
sym _printD = AAB // DOS3.3 command
sym printK = AC7 // centered
sym _ADE = ADE // dw next 2 bytes after JSR
sym _0B25 = B25 // dw next 2 bytes after JSR
sym _0B2F = B2F // dw next 2 bytes after JSR
sym _StackBytes2 = B3B // dw next 2 bytes
sym _0B5C = B5C // dw next 2 bytes after JSR
sym _0B86 = B86 // dw next 2 bytes after JSR
sym _0BA7 = BA7 // dw next 2 bytes afer JSR
sym RowtoXY = CA3 // X = A & 7, Y = (A & 78) >> 3
sym TileHgrY = CB1 // called from
db ScreenLo D13
db ScreenHi D19
sym FUNC_0CC2 = CC2 // $6B to $4200,X
sym GetTileDest = D12 // reset screen dst ptr; called from DrawTile .. $61=#$21, $62=#$21, $62=#$12
sym getAY_4342 = DC4 // Y=$4342 A=$4343
dw 4342:4343
sym _ECB = ECB // dw next 2 bytes after JSR
sym _EBA = EBA // dw next 2 bytes after JSR
db WallAND F84:F8F // used at DDA
sym _F90 = F90 // dw next 2 bytes after JSR
sym _F9A = F9A // dw next 2 bytes after JSR
sym Random = 898
sym SndWall = FE8
sym PrintChest = 5CCC
sym ShakeScrn = 14CF // called by 11EA 11ED 11F9 11FC
sym FUNC_112A = 112A // delay A ??
sym FUNC_1B07 = 1B07 // unknown
sym FUNC_1B17 = 1B17 // jump table at 1B2D .. 1B49
sym FUNC_1B4D = 1B4D
sym FUNC_1C72 = 1C72
sym FUNC_1CB9 = 1CB9
sym FUNC_1B78 = 1B78
sym FUNC_1BE4 = 1BE4
sym FUNC_1CD7 = 1CD7
sym FUNC_1CF5 = 1CF5
sym FUNC_1D0B = 1D0B
sym OnResetEsc = 1EC7 // $3F2 init at 1187 .. or if ESCAPE pressed .. save game
// OPEN ^TEXT
// BLOAD SEKTOR,A$4004
// BSAVE CASTLE,A$4004,L$3DFC
// BSAVE BACKUP,A$4004,L$3DFC
//$E21 Print Ranks:
// PRIVATE
// CORPORAL
// SERGEANT
// LIEUTENANT
// CAPTAIN
// COLONEL
// GENERAL
// FIELD MARSHAL

sym JUMP_0EB7 = EB7
sym RTS_0DC3 = DC3
sym RTS_0EB9 = 0EB9
sym RTS_1BE3 = 1BE3

ASC A06:A15 // TRACK ERROR

sym DrawMap = CCC // $CE6 do 0x48 = 72 tiles
sym DrawTile = D1D // called from CD4 .. LDX #Tile
sym Draw_0D2A = 0D2A
ASC D47:D4B // "TTTTT" // draw map tile
ASC D61:D66 // "TTTTT" // draw map tile
sym isTileTop = D3A
sym isTileBot = D4D
sym isTileLeft = D67
sym isTileRight = D79
sym isTileStair = D95
db curTile D68
ASC D73:D77 // U<cr>U<cr>T<cr>
ASC D8F:D93 // U<cr>U<cr>T<cr>
ASC DAD:DAF // +++
ASC DB7:DB9 // ***
ASC DBE:DC1 // <cr>+++
dw 1034:1035 // $106A
dw 1067:1068 // $106A
ASC 10B5:10BF // 3 spaces, <cr>, 3 spaces <cr>
dw 10FE:10FF
ASC 1103:1114 // "YOU WERE BLOWN UP "
ASC 1115:1125 // "IN THE EXPLOSION!"
dw 1176:1177 // $1D47
dw 117D:117E // $1D2E
dw 1182:1183 // $1D21
dw 121A:121B // $1D2E
dw 121F:1220 // $1D21
dw 1268:1269 // $0016
dw 126D:126E // $2801
dw 12C4:12C5 // $0303
dw 136C:136D // $0016
dw 1371:1372 // $2801
dw 13A6:13A7 // $0303
dw 1475:1476 // $1D47
dw 147A:147B // $1D21

ASC 16DA:16DC // U <cr>
dw 16EF:16F0
ASC 16F4:16FF // "B <cr> VLZ <cr> Q <cr>T // unknown purpose
ASC 1700:1713 // T x 20 times // unknown purpose
dw 1718:1719
ASC 1734:173F // "BLOAD PICEX"
ASC 171D:1729 // YOU ESCAPED!
dw 1749:174A // $1315
ASC 174E:175E // WITH THE PLAN
ASC 1835:1843 // BLOAD ^VOCAB,A$
// 1845: Bload @ $5E38
dw 19C1:19C2 // $1AFF
dw 1A2C:1A2D // $1AFF
dw 1B14:1B15 // $1AFF
ASC 1CC4:1CCF // 456 <cr> 2L3 <cr> 789 // unknown purpose
ASC 1CE2:1CED // 3 space <cr> 1 <cr> 3 space

ASC 1D21:1D2C
ASC 1D2E:1D39

dw 1ED3:1ED4
ASC 1ED8:1EE7 // "SAVING THE GAME" // esc pressed

// Map Tiles are always 5x5 that overlap
// 00 = Empty
// 01 = Left Wall
// 02 = Right Wall
// 04 = Top Wall
// 08 = Bottom Wall
// 10 = Stairs
//hgr// Locked Doors and Guards are stored elsewhere
db map_row1 4000:4007
db map_row2 4008:400F
db map_row3 4010:4017
db map_row4 4018:401F
db map_row5 4020:4027
db map_row6 4028:402F
db map_row7 4030:4037
db map_row8 4038:403F
db map_row9 4040:4047

sym FUNC_4F6A = 4F6A
dw 4F6D:4F6E // $4C05
dw 4F8E:4F8F // $4C05
dw 4FE1:4FE2 // $4C05
dw 5035:5036 // $4C05
dw 506D:506E // $0303
dw 5072:5073 // $4C05
dw 5094:5095 // $4C05
dw 50A6:50A7 // $4C05
dw 50DB:50DC // $0303
dw 50E9:50EA // $4C05
ASC 510D:5110 // !"#
dw 5118:5119 // $5022
ASC 5138:5139 // !
dw 5146:5147 // $5022
dw 5161:5162 // $0016
ASC 5166:5177 // " PUTTING ON THE "
ASC 5178:518B // "VEST (10 SECONDS...)
DW 51A9:51AA // $0016
ASC 51AE:51BC // 14 spaces
ASC 51BD:51C9 // "SEARCHING..."
dw 51D5:51D6 // $5022
dw 51DF:51E0 // $0016
dw 51E4:51E5 // $2801
dw 51F4:51F5 // $5022
sym GuardPockets = 51F7
dw 521B:521C // $0016
ASC 5221:522F // YOU HAVE A "
ASC 5230:523B // "BULLETPROOF "
ASC 523C:5246 // "VEST."
dw 524E:524F // $0016
ASC 5266:5275 // " BULLETPROOF "
ASC 5276:5287 // "VEST! (U TO USE)"
ASC 5290:529B // 11 spaces
ASC 52D2:52D9 // " BULLETS"
ASC 52E6:52EA // "AND "
ASC 52F4:52FC // "A GRENADE"
ASC 5315:5320 // "NOTHING ELSE"
ASC 5328:532B // "KEYS"
ASC 5340:5346 // "NOTHING" // search guard pockets!
ASC 534B:534C // "!"
dw 536D:536E // $5022
ASC 539F:53A0 // "U"
ASC 53AB:53B0 // <cr> <cr> <cr>
ASC 53B6:53BB // <cr>0<cr>0<cr>0
dw 53E0:53E1 // $0016
dw 53E5:53E6 // $2801
dw 53EA:53EB // $0916
ASC 53F4:53FF // "LOCKED AND NO KEY"
ASC 5400:5408
ASC 540E:542B // "TRYING YOUR KEYS (9 SECONDS)"
dw 5452:5453 // $0016
ASC 5457:5460 // 10 spaces
ASC 5470:547E // "STILL LOCKED!"
ASC 5486:5491 // "IT'S OPEN!"
ASC 54BD:54CA // "IT"S CLOSED"
dw 5518:5519 // $4C05
dw 5525:5526 // $4C05

dw 58A8:58A9 // $4915
dw 58AE:58AF // $490D
dw 58D5:58D6 // $5877
ASC 5986:5990 // "234 ... 789"
ASC 59E4:59F1 // "IT WILL TAKE "
ASC 59FC:5A05 // " SECONDS!"
ASC 5A38:5A41 // "(U TO USE)"
ASC 5A95:5AA0 // IT'S EMPTY.
dw 5AA8:5AA9
ASC 5AAD:5AB5 // " GETTING "
ASC 5ABD // (
ASC 5AD0:5AD8 // "SECONDS)"
dw 5909:590A // $5877
dw 591F:5920 // $5877
dw 5B10:5B11
DB aItemTime 5B15:5B24 // Time to use item in chest
// Chest Type 0 .. 15
ASC 5CF0:5CF4 // "EMPTY" Contents = 0
ASC 5CF6:5CFC // "BULLETS"
ASC 5CFE:5D05 // "GRENADES"
ASC 5D07:5D0E // "UNIFORMS"
ASC 5D10:5D20 // "BULLETPROOF VESTS"
ASC 5D22:5D27 // "MEDALS"
ASC 5D29:5D30 // "SCHNAPPS"
ASC 5D32:5D3A // "BRATWURST"
ASC 5D3C:5D45 // "SAUERKRAUT" // Type = 8
ASC 5D47:5D4D // "BULLETS"
ASC 5D4F:5D56 // "GRENADES"
ASC 5D58:5D5F // "UNIFORMS"
ASC 5D61:5D71 // "BULLETPROOF VESTS" // Type=12
ASC 5D73:5D7F // "LIEBFRAUMILCH"
ASC 5D81:5D8B // "CANNONBALLS"
ASC 5D8D:5D95 // "WAR PLANS" // Type = 15

// "Speech" Speaker
dw 5E36:5E37 // NextSpeech1 $6062
dw 6062:6063 // NextSpeech2 $624B
dw 624B:624C // NextSpeech2 $661A
dw 661A:661B // NextSpeech3 $6B7B
dw 6B7B:6B7C // NextSpeech4 $7027
dw 7027:7028 // NextSpeech5 $756E
dw 756E:756F // NextSpeech6 $7804
dw 7804:7805 // NextSpeech7 $7B77
dw 7B77:7B78 // NextSpeech8 $819C
dw 819C:819D // NextSpeech9 $847A
dw 847A:847B // NextSpeech10 $86F6
dw 86F6:86F7 // NextSpeech11 8B9C -- none
ASC 5E38:5E48 // ACHTUNG
ASC 6064:6074 // HALT
ASC 624D:625D // EEYAGH
ASC 661C:662C // YIEEE
ASC 6B7D:6B8D // CHWEINHUND
ASC 7029:7039 // SS
ASC 7570:7580 // PHOLGE
ASC 7806:7816 // KAMERAD
ASC 7B79:7B89 // WASISTLOS
ASC 819E:81AE // FEUER
ASC 847C:848C // DAPUT
ASC 86F8:8708 // UFWIEDERSEN

ASC 5E49:5E55 // Bug in speech 1 name?? 5E54: $17D8 should be A0 A0
dw 5E56:5E57
dw 5E58:5E59
ASC 6075:6081
dw 6082:6083
dw 6084:6085
ASC 6B8E:6B9A
ASC 703A:7046
ASC 7581:758D
ASC 7817:7823
ASC 7B8A:7B96
ASC 81AF:81BB
ASC 848D:8499
ASC 8709:8715

- - - 8< - - -

Back to fixing AppleWin's colors and debugger :-)

Happy reverse engineering!
Michael




awanderin

unread,
Dec 15, 2014, 11:25:00 PM12/15/14
to
Michael AppleWin Debugger Dev <michael....@gmail.com> writes:

[ Lots of interesting stuff clipped]

I was inspired to post my prodosified version because you mentioned you
were going to post your disassembly. I tend to sit on stuff and not put
it "out there" far too often.


> For some reason the save game saves address from 4004:7DFF (inclusive):
>
> BSAVE CASTLE,A$4004,L$3DFC

The reason for this "odd" behavior is that the game actually doesn't
always use DOS 3.2's read routines. For random file-access, it walks
the Track/Sector-List sector and uses RWTSS to read/write the sectors needed.

Binary (B) files in DOS 3.2 and DOS 3.3 always started with two bytes of
Address (A$) and two bytes of Length (L$).

So if you load the raw first-sector of a file at $4000 the first four
bytes are the address and length.

When the game copies CASTLE to BACKUP, it uses BLOAD/BSAVE but during
game-play it reads/writes just the next sector it needs, and for that it
bypasses DOS and reads the file-structure directly off the disk.


[Rest of notes clipped].

I will save your notes. I looked a bit into other parts of the
Wolfenstein programs but mostly I was looking for disk-access routines
and ignored the rest.


I did however, look at some of the graphics routines. I wrote this to
see all the characters in the font it uses to draw the game:

----------------------------------------

#!/usr/bin/env python

import sys


if __name__ == '__main__':
if not sys.argv[1:]:
sys.exit( 2 )

charset = open( sys.argv[1], 'rb' ).read()

offset = 0
char = 0
map = {}


while offset < len( charset ):
map[char] = []

for byte in charset[offset: offset + 8]:
row = ''.join( ['#' if (ord( byte ) & bit) else ' '
for bit in [1<<x for x in xrange( 0, 7 )]] )
map[char].append( row )


offset += 8
char += 1

CHARS_PER_ROW = 8
for y in xrange( len( map ) // 8 ):
for y1 in xrange( 10 ):
for x in xrange( CHARS_PER_ROW ):
char = y * CHARS_PER_ROW + x

if y1 == 0:
print ' 0x{0:02x} '.format( char ),
elif y1 == 1:
print '------- ',
else:
print '{0:<8}'.format( map[char][y1 - 2] ),

print
print

----------------------------------------

And here's the output:

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
------- ------- ------- ------- ------- ------- ------- -------
### # #### ### ### ##### ##### ####
# # # # # # # # # # # # #
# # # # # # # # # # # #
# ### # # #### # # # #### #### #
# ## ##### # # # # # # # # ##
# # # # # # # # # # # # #
#### # # #### ### ### ##### # ####


0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f
------- ------- ------- ------- ------- ------- ------- -------
# # ### # # # # # # # # ###
# # # # # # # ## ## # # # #
# # # # # # # ##### ## # # #
##### # # ## # # # # # # # # #
# # # # # # # # # # ## # #
# # # # # # # # # # # # # #
# # ### ## # # ##### # # # # ###


0x10 0x11 0x12 0x13 0x14 0x15 0x16 0x17
------- ------- ------- ------- ------- ------- ------- -------
#### ### #### ### ##### # # # # # #
# # # # # # # # # # # # # # #
# # # # # # # # # # # # # #
#### # # #### ### # # # # # # # #
# # # # # # # # # # # # #####
# # # # # # # # # # # # ## ##
# ## # # # ### # ### # # #


0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f
------- ------- ------- ------- ------- ------- ------- -------
# # # # ##### #### ####
# # # # # ## # ##
# # # # # ## # ## #
# # # ## # ## # #
# # # # ## # ## # #
# # # # ## # ##
# # # ##### ## ##
#### #### #######

0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27
------- ------- ------- ------- ------- ------- ------- -------
# # # ### # # # # #
# # # # #### ## ## # # #
# # # # # # # # #
# # ### # # #
# # # ## #
#### # #
# # ## #


0x28 0x29 0x2a 0x2b 0x2c 0x2d 0x2e 0x2f
------- ------- ------- ------- ------- ------- ------- -------
# # #
# # # # # # #
# # ### # #
# # # ##### ##### #
# # ### # #
# # # # # # # #
# # # # # #
# # #

0x30 0x31 0x32 0x33 0x34 0x35 0x36 0x37
------- ------- ------- ------- ------- ------- ------- -------
### # #### ###### # ###### ### ######
# # ## # # # ## # # #
# ## # # # # # ##### # #
# # # # ## ## # # # #### #
## # # # # ###### # # # #
# # # # # # # # # # # #
### ### ###### ### # #### ### #


0x38 0x39 0x3a 0x3b 0x3c 0x3d 0x3e 0x3f
------- ------- ------- ------- ------- ------- ------- -------
### ### # # ##
# # # # # # # #
# # # # # # # #
### #### # # # ##### # #
# # # # # #
# # # # # # ##### # #
### ### # # #
# #

0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47
------- ------- ------- ------- ------- ------- ------- -------
### ### ### ### ##### ##### ##### #####
##### ##### ##### ##### ##### ## # # ## # #
# # # # ### ### # ##### # ### # ## # # ## # #
## ## ##### ##### ##### # # # ##### ##### #####
### #### #### ### ### #### #### ###
# # # # # # # #
##### ##### ##### ##### ##### ##### ##### #####
####### ####### ####### ####### ####### ####### ####### #######

0x48 0x49 0x4a 0x4b 0x4c 0x4d 0x4e 0x4f
------- ------- ------- ------- ------- ------- ------- -------
## ## ## ## ## ## #### ####### ####### ## ## # #######
## ## ## ## ## ## #### ####### # # # # ## ## ## ##
## ## ## ## ## ## #### ####### ### # # ## ## # # # #
## ## ## ## ## ## # # ####### # # # ## ## # # # #
# # # # # # # # ####### # # ### ####### # # # #
# # # # # # # # ####### # # # ####### # # #
# # # ## ## # # ## ####### ####### ####### ## ##
## ## ## ## ## ####### ####### ####### #######

0x50 0x51 0x52 0x53 0x54 0x55 0x56 0x57
------- ------- ------- ------- ------- ------- ------- -------
## ## ##### ##### ## ## ####### ####### # #
## ## ### ### ## ## # # # # ## ##
#### #### ##### #### # # # # # #
#### ### ### #### ####### ####### # #
# # ## ## # # ####### # #
# # # # # # # # # # # #
# # # # # # # # # # # #
#### ## ## ## ## #### ####### # #

0x58 0x59 0x5a 0x5b 0x5c 0x5d 0x5e 0x5f
------- ------- ------- ------- ------- ------- ------- -------
# # # # # # # # # # #
# ## # # # # # # # # ##
# # # # # # ## # # # #
# # ###### # # # # ### # # # ###### #
# # ## # # # # # # ## #
### # # # # # # # # #
## # # # # # #
# # #

0x60 0x61 0x62 0x63 0x64 0x65 0x66 0x67
------- ------- ------- ------- ------- ------- ------- -------
# # # ######
# # # # # #
# # # ## ######
# # #
# # ### # # ####
#### # ####### ### # # ### # # #
## ### ### ## ## # ## ## # # ## #
## # ####### ## ### # # # # # # #

0x68 0x69 0x6a 0x6b 0x6c 0x6d 0x6e 0x6f
------- ------- ------- ------- ------- ------- ------- -------
####### ##### ####### # #### ### #
## # # # # ####### # ### #### ### #
####### ##### # # # # # # # ## ### #
## ####### ####### ### ### # # ### #
####### ####### ### ### # # ### #
# # ####### ####### # # # # # ### #
# # ### # ## # ### #
# # ####### ####### # ## ####

0x70 0x71 0x72 0x73 0x74 0x75 0x76 0x77
------- ------- ------- ------- ------- ------- ------- -------
# # # # ###### ###### # # #######
# ### # ####### ##### # ## #####
# ### # ## ## # ## ## ###
# ###### ## ## #### ## # ### ### # # # ##
# ### # ##### ###### ### ####### ## ## # ##
# # ## #### ### #### ####### #### # #
# # # ## #### ###### ##### ####### #### # #
# # # ####### ####### ###### ####### #######

0x78 0x79 0x7a 0x7b 0x7c 0x7d 0x7e 0x7f
------- ------- ------- ------- ------- ------- ------- -------
####### ##### # ## ## #
####### ####### # ### #
####### ##### # ####### # #### ####### #######
####### #### ## ## ##### ####### ##### #
#### ## # # # # # # # ###### ####### #### #
### # # # # # # # # ####### ####### ### ##
# # # # # # # # ####### #### ### # #
# # ## ## # ## #


--
--
Jerry awanderin at gmail dot com

xorxif

unread,
Dec 22, 2014, 12:59:54 AM12/22/14
to
This is all GREAT stuff, perfect for making a "romhack" type version of
the game.

There is some stuff about the data format of Beyond Castle Wolfenstein
in a couple of issues of Hardcore Computist that seems to indicate
similar ideas and data structures were used in the programming of that game.

I have played (and continue to play occasionally,) this game and BCW
since the early 80's. Even though I eventually extended my gaming to
newer computers and consoles, these pioneering concepts have always
stuck with me and helped me to imagine what is possible.

Ideally, I would love to be able to see, modify, and extend the routines
that govern guard and SS behavior, (i.e. having guards throw grenades,
which I was convinced at one time I had seen happen, but may have
dreamed it, considering how much I played this game back in the day...)
I would also love to have every item have a clear and discernible
effect, and even be able to add more items able to be generated in the
chests.

This article says Silas Warner was inspired by the look and feel of the
Berzerk arcade game and by the film The Guns of Navarone.

http://www.filfre.net/2012/04/castle-wolfenstein/

In turn, others took inspiration from him, most notably Hideo Kojima, in
the original design of the MSX version of Metal Gear.

I had thought over the years about changes that could be made to the
game to make it more fun, that were still within the original
limitations of the system it was on, but using all that has been learned
about game design and player psychology and motivation over the years.

I think this would be a great deal of fun to fiddle with. Anyone else
think this would be fun?

- xorxif

Michael AppleWin Debugger Dev

unread,
Dec 22, 2014, 1:23:28 PM12/22/14
to
On Sunday, December 21, 2014 9:59:54 PM UTC-8, xorxif wrote:
> This is all GREAT stuff, perfect for making a "romhack" type version of
> the game.

Thanks for the context and back story! Was a great read!

It is funny how many "firsts" were first done on Apple games!

* Castle Wolfenstein - first game to have digitized speech
* Conan - first game to use a 1-bit stencil buffer
* Karateka - first game to have cutscenes

Someday I hope to have a map editor for Castle Wolfenstein .. the ability to place guards, and tweak the AI would be awesome.

Sadly, I won't have time to rip the sprites in CW for a while ... still need to track those down :-)

johnsonlam.hk

unread,
Dec 28, 2014, 2:03:12 AM12/28/14
to
Great job!

Moose

unread,
Apr 4, 2015, 6:54:44 PM4/4/15
to
On Tuesday, December 23, 2014 at 4:23:28 AM UTC+10, Michael AppleWin Debugger Dev wrote:
> Someday I hope to have a map editor for Castle Wolfenstein .. the ability to place guards, and tweak the AI would be awesome.

Yes, a level / map editor would be great.
0 new messages