Prince-of-Persia-Apple-II

A running-jumping-swordfighting game Jordan Mechner made on the Apple II from 1985-89
Log | Files | Refs | README | LICENSE

COMMENTS.S (13278B)


      1 * comments
      2 *-------------------------------
      3 *
      4 * M  O  V  E  R
      5 *
      6 *-------------------------------
      7 *
      8 * Routines to keep track of moving objects are contained
      9 * in the file MOVER.
     10 *
     11 * There are 2 types of moving objects: Transitional objects
     12 * (TROBs) and mobile objects (MOBs).
     13 *
     14 * TROBs (e.g. gate, spikes, pressplate, torch) can have moving
     15 * parts & change appearance, but remain in a fixed location.
     16 *
     17 * MOBs (falling floor) can move all over the place, including
     18 * between screens.
     19 *
     20 *-------------------------------
     21 *
     22 * TROBs are kept track of in a data structure called
     23 * the "trans list" as follows:
     24 *
     25 * numtrans = # of active TROBs
     26 *
     27 * For x = 1 to numtrans:
     28 *
     29 *  trloc,x = block location (0-29)
     30 *  trscrn,x = screen # (1-24)
     31 *  trdirec,x = direction of motion (means something different
     32 *   for different kinds of objects)
     33 *
     34 * When an object stops moving, we set its trdirec = -1, then
     35 * remove the object from trans list on the next cycle.
     36 *
     37 *-------------------------------
     38 *
     39 * MOBs are kept track of in a similar data structure called
     40 * the "MOB list":
     41 *
     42 * nummob = # of active MOBs
     43 *
     44 * For x = 1 to nummob:
     45 *
     46 *  mobx,x = byte (0-39)
     47 *  moby,x = y-coord
     48 *  mobscrn,x = screen #
     49 *  mobvel,x = velocity
     50 *  mobtype,x = type
     51 *    0: falling floor
     52 *    (No other MOB types defined at present)
     53 *  moblevel,x = level (0-2)
     54 *
     55 *-------------------------------
     56 *
     57 *  The basic routine in MOVER is ANIMTRANS.  This
     58 *  routine, which is called once per cycle, advances
     59 *  all active TROBs to their next phase (this includes
     60 *  deleting TROBs that become inactive) and marks the
     61 *  appropriate redraw buffers for each TROB.
     62 *
     63 *  Other routines such as TRIGSPIKES, PUSHPP, BREAKLOOSE,
     64 *  etc. are called to add new TROBs to the trans list (when,
     65 *  for example, a character jumps over spikes or steps on
     66 *  a pressure plate or loose floor).
     67 *
     68 *  The routine ANIMMOBS performs the same function for
     69 *  the MOB list that ANIMTRANS does for the trans list.
     70 *  It advances all active MOBs to the position they will
     71 *  occupy in the next frame.
     72 *
     73 *  Example: When a character steps on a loose floor, the
     74 *  control routine senses this & puts in a call to
     75 *  BREAKLOOSE (which adds the loose floor to the trans
     76 *  list).  For the next 10 frames or so, the loose floor
     77 *  wiggles (under the control of ANIMTRANS) until ANIMTRANS
     78 *  decides it's time for it to fall.  At that point, the
     79 *  loose floor is deleted from the trans list, the block
     80 *  is replaced by "empty space", and a new MOB is
     81 *  created to take its place.  Under the control of
     82 *  ANIMMOBS, the MOB then falls until it hits the ground,
     83 *  at which point ANIMMOBS deletes the falling floor from
     84 *  the MOB list and changes the objid of the block it landed
     85 *  on to "rubble."
     86 *
     87 *-------------------------------
     88 *
     89 *  F  R  A  M  E  A  D  V
     90 *
     91 *-------------------------------
     92 *
     93 *  IMAGE LISTS
     94 *
     95 *  FRAMEADV never calls hires routines directly.  Instead,
     96 *  parameters of images to be drawn are stored in "image lists."
     97 *
     98 *  There are 6 separate image lists:
     99 *
    100 *  bg:   Images in background plane (drawn first)
    101 *        X, Y, IMG, OP
    102 *
    103 *  wipe: Solid-color wipes (drawn with b.g. plane)
    104 *        X, Y, H, W, COL
    105 *
    106 *  fg:   Images in foreground plane (drawn last)
    107 *        X, Y, IMG, OP
    108 *
    109 *  mid:  Images between b.g. and f.g. planes
    110 *        X, OFF, Y, IMG, OP, TYP, CU, CD, CL, CR
    111 *
    112 *  msg:  Images in message plane (drawn last of all)
    113 *        X, OFF, Y, IMG, OP
    114 *
    115 *  gen:  General instructions (e.g. clear screen)
    116 *
    117 *
    118 *  Explanation of parameters:
    119 *
    120 *  X    = X-coord (in bytes)
    121 *  OFF  = X-offset (0-6)
    122 *  Y    = Y-coord
    123 *  IMG  = image # in table (1-n)
    124 *  OP   = opacity
    125 *  TYP  = image type (for mid only)
    126 *  CU   = top cutoff
    127 *  CD   = bottom cutoff
    128 *  CL   = left cutoff
    129 *  CR   = right cutoff
    130 *  H    = height
    131 *  W    = width (in bytes)
    132 *  COL  = color (for wipe only)
    133 *
    134 *  NOTE--bg, fg, and wipe calls assume offset=0
    135 *
    136 *
    137 *  There is also an "object list" with params similar to
    138 *  mid list:
    139 *
    140 *        X, OFF, Y, IMG, FACE, TYP, CU, CD, CL, CR
    141 *
    142 *  Note that obj list has 2 additional params:
    143 *
    144 *  objFACE = left/right
    145 *  objTYP  = object type (Not to be confused with midTYP)
    146 *
    147 *  The object list has one entry for each object to be
    148 *  drawn (e.g., "kid," "falling floor").  FRAMEADV uses
    149 *  the object list to build the actual mid list
    150 *  of images to be drawn.  E.g., the single object "falling
    151 *  floor" might translate into 3 separate images:
    152 *  A-section, B-section, and D-section.
    153 *
    154 *-------------------------------
    155 *
    156 *  REDRAW BUFFERS
    157 *
    158 *  Each redraw buffer contains 30 counters, one for each
    159 *  block on screen: 0 = skip, non-0 = redraw and decrement.
    160 *
    161 *  REDBUF:
    162 *  The most general-purpose buffer.  Marking REDBUF for a
    163 *  block will cause all sections of the block to be redrawn.
    164 *
    165 *  WIPEBUF:
    166 *  Wipe square (usually to black).  WHITEBUF contains
    167 *  wipe height, in lines.
    168 *
    169 *  Marking both REDBUF and WIPEBUF for a block will cause
    170 *  the entire block to be erased & redrawn.  This is the
    171 *  safest way to redraw a block.
    172 *
    173 *  MOVEBUF:
    174 *  Refers only to movable portion of object (e.g. lowering
    175 *  gate).  Superseded by REDBUF.
    176 *
    177 *  FREDBUF:
    178 *  Refers only to foreground plane.  Marked when character
    179 *  goes behind a post or other object with a frontpiece.
    180 *  Superseded by REDBUF.
    181 *
    182 *  FLOORBUF:
    183 *  Refers to floorpieces.  Marked to the right of a
    184 *  falling or hanging character.  FLOORBUF causes floorpiece
    185 *  to be drawn in the mid plane (where it will cover up
    186 *  character if appropriate).
    187 *
    188 *  HALFBUF:
    189 *  Like FLOORBUF, but redraws a triangular section of
    190 *  the floorpiece instead of the whole thing.  Used when
    191 *  a character climbs up on the left side of a floorpiece
    192 *  and we want to mask out his lower body while letting his
    193 *  upper body show.  (Superseded by FLOORBUF.)
    194 *
    195 *  OBJBUF:
    196 *  Marked whenever objects need to be drawn in a given block.
    197 *  (Objects are always the last mid elements drawn in
    198 *  a block.  Objects are assigned to blocks based on
    199 *  their lower left x-y coords.  Characters are considered
    200 *  objects.  There can be multiple objects in a given block.)
    201 *
    202 *  TOPBUF:
    203 *  10-byte buffer for row of D-sections across top of screen
    204 *  (from screen above).
    205 *
    206 *  Note that TOPBUF is a 10-byte buffer while the others are
    207 *  all 30 bytes.
    208 *
    209 *-------------------------------
    210 *
    211 *  The specific routines called by SURE (in FRAMEADV) for
    212 *  each of these buffers are:
    213 *
    214 *  REDBUF: redblock (drawc, drawb, drawmb, drawd, drawmd,
    215 *     drawa, drawma, drawfrnt)
    216 *
    217 *  WIPEBUF: wipesq
    218 *
    219 *  MOVEBUF: drawc, drawmc, drawmb, drawma
    220 *
    221 *  FREDBUF: drawfrnt
    222 *
    223 *  FLOORBUF: drawfloor
    224 *
    225 *  HALFBUF: drawhalf
    226 *
    227 *  OBJBUF: drawobjs
    228 *
    229 *  TOPBUF: drawc, drawb, redrawd, drawmd, drawfrnt
    230 *
    231 *-------------------------------
    232 *
    233 *  B  L  U  E  P  R  I  N  T
    234 *
    235 *-------------------------------
    236 *
    237 *  LEVEL BLUEPRINT ($900 bytes)
    238 *
    239 *               Start      Length
    240 *               -----      ------
    241 *  BlueType     B700       720
    242 *  BlueSpec     B9D0       720
    243 *  LinkLoc      BCA0       256
    244 *  LinkMap      BDA0       256
    245 *  Map          BEA0       96
    246 *  Info         BF00       256
    247 *
    248 *  TOTAL: 2304 bytes
    249 *
    250 *-------------------------------
    251 *
    252 * BLUETYPE
    253 *
    254 * Bytes 0-29 describe screen #1
    255 * Bytes 30-59   "     screen #2
    256 * etc.
    257 * 24 screens total.
    258 *
    259 * Each BLUETYPE byte corresponds to one block.
    260 * (30 blocks per screen.)  Blocks are mapped
    261 * into BLUETYPE left-right, top-bottom.
    262 *
    263 * AND with #$1F to get the "objid," or object
    264 * identification number (0-31), of each block.
    265 *
    266 *-------------------------------
    267 *
    268 * BLUESPEC
    269 *
    270 * (Screen blocks mapped the same way as in BLUETYPE.)
    271 *
    272 * Taken together, each pair of corresponding bytes in
    273 * BLUETYPE and BLUESPEC contains all the information
    274 * about an object.  The BLUETYPE byte always contains
    275 * the object id.  The BLUESPEC byte functions differently
    276 * depending on what the object is.
    277 *
    278 * For movable objects (gates, spikes, torches, etc.)
    279 * BLUESPEC specifies the object's "state" (e.g. is it
    280 * open, closed, somewhere in between?)
    281 *
    282 * For static objects (floor, space, solid block, etc.)
    283 * BLUESPEC specifies the object's "pattern" (e.g. which
    284 * design appears on the wall behind it?)
    285 *
    286 * For pressure plates, the BLUESPEC byte tells which
    287 * gates the pressure plate controls.  Specifically, the
    288 * BLUESPEC byte is a pointer (0-255) to the first entry
    289 * in the link list for this pressure plate.
    290 *
    291 *-------------------------------
    292 *
    293 * Link list (LINKLOC/LINKMAP)
    294 *
    295 * Contains a list of the gates controlled by each pressure
    296 * plate.  Each pair of bytes specifies one plate-to-gate
    297 * linkage.  There can be up to 256 such linkages in a level.
    298 *
    299 * LINKLOC:
    300 *  Bits 0-4: gate screen posn (0-29)
    301 *  Bits 5-6: low 2 bits of gate screen # (1-24)
    302 *  Bit 7: 1 = this is last entry, 0 = more gates to come
    303 *
    304 * LINKMAP:
    305 *  Bits 0-4: pressplate timer (0-31)
    306 *  Bits 5-7: high 3 bits of gate screen #
    307 *
    308 * If a pressplate controls nothing, LINKLOC = FF; LINKMAP
    309 * still functions as pressplate timer.
    310 *
    311 *-------------------------------
    312 *
    313 * MAP
    314 *
    315 * Specifies how the 24 screens of the level are connected.
    316 *
    317 * Each screen gets 4 bytes corresponding to the screen #s
    318 * of the 4 adjacent screens.
    319 *
    320 * Bytes 0-3 = screen #1
    321 * Bytes 4-7 = screen #2
    322 * etc.
    323 *
    324 * For each screen:
    325 * Byte #1 = screen to left
    326 * Byte #2 = screen to right
    327 * Byte #3 = screen above
    328 * Byte #4 = screen below
    329 *
    330 *-------------------------------
    331 *
    332 *  INFO
    333 *
    334 *  Bytes 0-63: reserved for editor
    335 *
    336 *  Bytes 64-255: Information about starting positions
    337 *  of player & other characters on this level.
    338 *  (See GAMEEQ for details.)
    339 *
    340 *-------------------------------
    341 *
    342 *  S  E  Q  T  A  B  L  E
    343 *
    344 *-------------------------------
    345 *
    346 *  Frame def list:
    347 *
    348 *  1200 bytes allocated -- 240 frames, 5 bytes each
    349 *  (241-255 reserved as commands)
    350 *
    351 *  Frame definition consists of:
    352 *
    353 *  (1) Fimage
    354 *
    355 *     Bit 7 = chtable # (0-7), bit 2
    356 *
    357 *     Bits 0-6 = image # (0-127)
    358 *
    359 *     SUMMARY:
    360 *       $00 + x: chtable 1,2,3,4
    361 *       $80 + x: chtable 5,6,7,8
    362 *
    363 *  (2) Fsword
    364 *
    365 *     Bits 6-7 = chtable # (0-7), bits 0-1
    366 *
    367 *     Bits 0-5 = pointer to SWORDTAB frame (0-63)
    368 *
    369 *     SUMMARY:
    370 *       $00 + x: chtable 1,5
    371 *       $40 + x: chtable 2,6
    372 *       $80 + x: chtable 3,7
    373 *       $c0 + x: chtable 4,8
    374 *
    375 *  (3) Fdx
    376 *
    377 *     X-shift in pixels (+ = fwd, - = bkwd)
    378 *     (NOTE -- horizontal resolution is 140 pixels)
    379 *
    380 *  (4) Fdy
    381 *
    382 *     Y-shift in pixels (+ = down, - = up)
    383 *     (Frame #15 is defined as unshifted)
    384 *
    385 *  (5) Fcheck
    386 *
    387 *     Bit 7 = odd/even pixel
    388 *
    389 *     Bit 6 = 1 if floor check is required (i.e., if weight
    390 *       is on floor)
    391 *
    392 *     Bit 5 = 1 to "thin" this frame for collision detection
    393 *
    394 *     Bits 0-4 = number of pixels (0-31) from left edge of
    395 *       image block to base x-coord
    396 *       (usually center of foot bearing character's weight)
    397 *
    398 *     SUMMARY:
    399 *       $c0 + x: check, odd
    400 *       $40 + x: check, even
    401 *       $80 + x: no check, odd
    402 *       $00 + x: no check, even
    403 *
    404 *     + $20 to set bit 5
    405 *
    406 *-------------------------------
    407 *
    408 *  SEQPOINT is 2-byte pointer to character's current
    409 *  position in sequence table.
    410 *
    411 *  Seq pointer is incremented by 1 with each frame-advance.
    412 *
    413 *  CTRL can jump seq pointer around at will (e.g., in response
    414 *  to joystick command)
    415 *
    416 *  POSITIVE seq table values represent frame numbers.
    417 *  NEGATIVE values are instruction codes.
    418 *
    419 *  Sequence table instructions:
    420 *
    421 *   goto NN    jump seq pointer to NN (low byte first)
    422 *   aboutface  change KIDFACE direction
    423 *   up         up one floor
    424 *   down       down one floor
    425 *   chx N      KIDX := KIDX + N (BEFORE we draw next frame)
    426 *   chy N      KIDY := KIDY + N (ditto)
    427 *   act N      change action code to N
    428 *   setfall X,Y  set initial x,y velocity for freefall
    429 *
    430 *  Action codes:
    431 *
    432 *  -1 = dead
    433 *   0 = standing still
    434 *   1 = running, jumping, other actions
    435 *       that require a floor beneath your feet
    436 *   2 = hanging, climbing, and all other actions that
    437 *       require holding onto a ledge
    438 *   3 = in midair (briefly)
    439 *   4 = in freefall
    440 *   5 = being bumped
    441 *   6 = hanging straight
    442 *   7 = turning
    443 *
    444 *  Screen resolution is 140 x 192.
    445 *
    446 *-------------------------------
    447 *
    448 *  NOTE: Frame table offsets are TEMPORARY; sequence table
    449 *  offsets are PERMANENT.
    450 *
    451 *  CTRL draws each frame at [KIDX + Fdx, KIDY + Fdy],
    452 *  but leaves KIDX & KIDY unchanged for the next frame.
    453 *  "Chx" and "Chy" instructions in sequence table, however,
    454 *  change KIDX & KIDY permanently.
    455 *
    456 *  For JUMPHANG, CLIMBUP, etc., the idea is for KIDX, KIDY &
    457 *  KIDLEVEL to keep the kid where he started -- at the end
    458 *  of the block behind & below the one he's hanging from --
    459 *  and use only the frame list x & y offsets, until he's back
    460 *  on the ground.  This way, we can branch into either HANGDROP
    461 *  or CLIMBUP from any point in HANG.
    462 *
    463 *  The first 4 frames of STARTRUN also use only the frame list
    464 *  offsets.  This lets us switch easily to, say, FULLSTEP
    465 *  or STANDJUMP.
    466 *
    467 *-------------------------------
    468 *
    469 *  M  I  S  C
    470 *
    471 *-------------------------------
    472 *
    473 * Potion IDs
    474 *
    475 * 0  Empty
    476 * 1  Regular healing
    477 * 2  Boost strength
    478 * 3  Weightless
    479 * 4  Upside down
    480 * 5  Poison
    481 *
    482 *-------------------------------
    483 *
    484 * Character IDs
    485 *
    486 * 0  Kid
    487 * 1  Shadow
    488 * 2  Guard
    489 * 3  Vizier (in game)
    490 * 4  Skeleton
    491 * 5  Princess (in princess cuts)
    492 * 6  Vizier (in princess cuts)
    493 *
    494 *-------------------------------
    495  lst off