' WOLF3D, ED. 2022-05-31, BY NATHANIEL BABIAK.
' 
' TAP `[B]` TO OPEN DOORS OR ACTIVATE HIDDEN/SECRET WALL PANELS (THE ORIGINAL SECRETS FROM
' 1992'S WOLFENSTEIN 3D ARE IN THERE, AND THERE'S FOUR MORE CLEARLY MARKED IN THE FIRST PART
' OF THE LEVEL).
' 
' HOLD `[B]` TO CIRCLE-STRAFE.
' 
' THIS RUNS AT 27 FPS MINIMUM, AND IS CAPPED AT 30 (IT DRAWS ONLY THE LEFT- OR RIGHT- HALF
' OF THE SCREEN EVERY FRAME, IF IT WAS FULL-SCREEN IT'D BE AROUND 14 FPS MINIMUM).  ALSO, IN
' THE SOURCE CODE, JUST BELOW `MAIN0:` YOU CAN UNCOMMENT THE FIRST `DATA` INSTRUCTION TO USE
' LOW-RESOLUTION TEXTURES, IT'LL RUN AROUND 45 FPS, CAPPED AT 60.
' 
' NEXT UP - POLISHING DOORS AND SECRET PANELS. THE DOORS AND SECRET PANELS CONTINUE TO MOVE
' DURING PAUSE, AND THE SOUNDS ARE TRASH (I'VE GOT SOME GREAT SFX FROM WAS8BIT TO
' IMPLEMENT), AND THE VOLUME DOESN'T DECREASE WITH DISTANCE.
' 
' AFTER THAT'S DONE, IT'S ON TO IN-GAME SPRITES AND 3D OBJECTS.
' 
' FYI - IN A REAL GAME, LEVELS WOULD BE DESIGNED SO SECRET PANELS COULDN'T OPEN TOWARDS YOU,
' BUT I THINK IT LOOKS COOL TO LEAVE IN THIS DEMO AS-IS, IT PROVIDES A GREAT SENSE OF HOW
' MUCH WORK GOES INTO THE 3D ILLUSIONS.
'

REPEAT
'SCRIPTING ENGINE.
  GLOBAL E_HOLD_A_FRAMES, E_HOLD_B_FRAMES, E_DOOR$, E_HIDE$, E_PCT_FLUSH0, E_PCT_FLUSH1
  DIM GLOBAL E_IS_DOOR(255), E_IS_PLAIN(255), E_IS_BOOL(255)
  DIM GLOBAL E_MAP(63,63), E_SX(7,2), E_SY(7,2)
  DIM GLOBAL E_DOORT(15), E_DOORX(15),   E_DOORY(15)
  DIM GLOBAL E_HIDET(15), E_HIDEX(15,2), E_HIDEY(15,2)
  GLOBAL E_AREA_HI, E_INTERLEAVE
  DIM GLOBAL E_AREAX(63), E_AREAY(63), E_AREA2INDEX(63,1), E_U(255,4)
'RAYCAST.
  DIM GLOBAL R_MAP(63,63)
  GLOBAL R_SCREENM5, R_LOCX,R_LOCY, R_ROTA,R_ROTX,R_ROTY, R_DSCREENX,R_DSCREENY
  GLOBAL R_BOXHEIGHT5
  GLOBAL R_RAYX,R_RAYY, R_DMAPX,R_DMAPY, R_DSX,R_DSY, R_SX,R_SY
  GLOBAL R_MAPX,R_MAPY, R_TILE,R_SIDE, R_RAYM,R_WALL, R_LOC_IN_DOOR,R_TILE_DOOR_JAMB
  DIM GLOBAL R_MAPXS(39), R_MAPYS(39), R_TILES(39), R_SIDES(39), R_RAYMS(39), R_WALLS(39)
'BACKGROUND.
  DIM GLOBAL B_TILE2TEX(191), B_TILE2CLR(191,1), B_PAL2CLR(7), B_BX2PAL(39)
  DIM GLOBAL B_TY0_2CH(31,15,15), B_TY1_2CH(31,15,15), B_TY2_2CH(31,15,15)
  GLOBAL B_BX0, B_CX, B_TEXNUM, B_CH, B_TX0, B_TY0, B_DTY
  DIM GLOBAL B_P0C0(127)
  GLOBAL B_CEILING, B_FLOOR, B_PCT2TX, B_PCT2TY, B_RAY0
'MOVEMENT.
  GLOBAL M_FWD0,M_STR0,M_ROT0,M_STR1,M_RAD1,M_RAD2,M_ITER
  GLOBAL M_PAUSE
  DIM GLOBAL M_MAP(63,63)
'INTERRUPTS.
  DIM GLOBAL I_BGY(127), I_P0C0(127), I_JUMP(127), I_BEACON(255)
'SPRITES
  GLOBAL S_LOCX, S_LOCY, S_ROTA, S_HLTH, S_AMMO, S_GOALX, S_GOALY, S_REDRAW_MAP
  DIM GLOBAL S_8080(3),S_4040(3),S_2020(3),S_1010(3),S_0808(3),S_0404(3),S_0202(3),S_0101(3)
  DIM GLOBAL S_MAP(127,95), S_ADR0(7,31), S_ADR8(7,31), S_TILE2CLR(255)
'SCREEN TRANSITIONS.
  DIM GLOBAL T_BXY2RAM(39, 95), T_BX2RAM(39)
'FPS.
  GLOBAL F_FRAMES, F_LAP, F_STR$, F_FRAME0, F_TIME
'DO IT!
  CALL MAIN
  END
UNTIL 1
SUB MAIN
  CALL E_LOAD( ROM( 3 ) )
  CALL R_LOAD
  RESTORE MAIN0
  MAIN0:
  'DATA 0,  7.999, 3.999, 2.50, 1
  DATA 1, 15.999, 7.999, 1.25, 2
  READ TEX_SIZE, B_PCT2TX, B_PCT2TY, B_RAY0, F_FRAME0
  CALL B_LOAD_TEX( ROM( 4 + TEX_SIZE ), 0, 15, TEX_SIZE )
  CALL S_LOAD
  CALL M_LOAD
  CALL E_INIT
  CALL R_INIT
  CALL S_INIT
  CALL M_INIT
  CALL T_INIT
  CALL B_LOAD_TILES
  CALL I_INIT
  CALL F_INIT
  DO
    CALL E_UPDATE
    CALL R_UPDATE
    CALL B_UPDATE
    CALL S_UPDATE
    CALL M_INPUT
    CALL F_UPDATE
  LOOP
END SUB
SUB E_LOAD( SRC0 )
  RESTORE E_LOAD0
  E_LOAD0:
  'NUMBER OF HIDDEN PANEL AREAS IN LEVEL THAT WILL YIELD MAP UPDATES.
  DATA   7
  'FOR EACH AREA (CX0, CY0, RECT_QTY), THEN FOR EACH RECT (CX1 ,CY1, CX2, CY2, USE_GOAL).
  DATA 30,48, 1, 27,44,30,49, 0
  DATA 10,57, 1,  5,58,11,62, 0
  DATA 18,21, 1, 17,19,20,20, 0
  DATA 17,20, 1,  9,17,17,20, 1
  DATA 13,17, 1, 12,14,15,17, 0
  DATA 27,13, 4, 10,5,24,11, 0, 0,0,0,20, 0, 0,0,63,0, 0, 61,0,63,25, 0
  DATA 41,13, 4, 10,5,24,11, 0, 0,0,0,20, 0, 0,0,63,0, 0, 61,0,63,25, 0
  READ AREA_QTY
  E_AREA_HI = AREA_QTY - 1
  INDEX1 = 0
  FOR A1 = 0 TO E_AREA_HI
    READ E_AREAX( A1 ), E_AREAY( A1 ), RECT_QTY
    E_AREA2INDEX( A1, 0 ) = INDEX1
    E_AREA2INDEX( A1, 1 ) = INDEX1 + RECT_QTY - 1
    ADD INDEX1, RECT_QTY
    FOR R1 = E_AREA2INDEX( A1, 0 ) TO E_AREA2INDEX( A1, 1 )
      READ E_U(R1,0), E_U(R1,1), E_U(R1,2), E_U(R1,3), E_U(R1,4)
    NEXT R1
  NEXT A1
  DATA 136, 137, 138, 139, 140, 141, 142, 143
  REPEAT
    READ TILE0
    E_IS_DOOR( TILE0 ) = -1
  UNTIL TILE0 = 143
  FOR TILE0 = 1 TO 255
    E_IS_PLAIN( TILE0 ) = NOT E_IS_DOOR( TILE0 )
  NEXT TILE0
  DATA 170, 171, 172, 173, 174, 175
  REPEAT
    READ TILE0
    E_IS_BOOL( TILE0 ) = -1
  UNTIL TILE0 = 175
  CY2 = PEEK( SRC0 + 3 ) - 1
  CX2 = PEEK( SRC0 + 2 ) - 1
  SRC1 = SRC0 + 4
  FOR CY1= CY2 TO 0 STEP -1
    FOR CX1 = 0 TO CX2
      'PEEKW ALWAYS POSITIVE BECAUSE BG DATA ATTRIBUTE BIT 7 UNUSED.
      WORD = PEEKW( SRC1 )
      E_MAP( CX1, CY1 ) = WORD
      ADD SRC1, 2
    NEXT CX1
  NEXT CY1
END SUB
SUB E_INIT
  E_DOOR$ = "FFFFFFFFFFFFFFF"
  E_HIDE$ = "FFFFFFFFFFFFFFF"
  RESTORE E_INIT0
  E_INIT0:
  'S_ROTA                0                    1                     2                     3
  DATA  1,-1,  1, 0,  1, 1,  0, 1,  1, 0,  1, 1,  -1, 1,  0, 1,  1, 1,  -1, 0, -1, 1,  0, 1
  'S_ROTA                4                    5                     6                     7
  DATA -1,-1, -1, 0, -1, 1, -1, 0, -1,-1,  0,-1,  -1,-1,  0,-1,  1,-1,   0,-1,  1,-1,  1, 0
  FOR ROTA = 0 TO 7
    READ E_SX(ROTA,0),E_SY(ROTA,0),  E_SX(ROTA,1),E_SY(ROTA,1),  E_SX(ROTA,2),E_SY(ROTA,2)
  NEXT ROTA
END SUB
SUB E_UPDATE
  'ALTERNATIVE TO 'TAP' KEYWORD AS RENDERING SPEED IS 15 TO 30 FPS (NOT 60).
  IF BUTTON(0,0) THEN INC E_HOLD_A_FRAMES ELSE E_HOLD_A_FRAMES = 0
  IF BUTTON(0,1) THEN INC E_HOLD_B_FRAMES ELSE E_HOLD_B_FRAMES = 0
  'TOGGLE INTERLEAVE. I HATE IT, BUT I NEED THE CLOCK CYCLES IT FREES UP.
  E_INTERLEAVE = NOT E_INTERLEAVE
  'CHECK FOR [B] 'USE' BUTTON PRESS, FIND ANY DOORS.
  IF E_HOLD_B_FRAMES = 1 THEN
    FOR CHECK = 0 TO 2
      CX = INT( R_LOCX ) + E_SX( S_ROTA, CHECK )
      CY = INT( R_LOCY ) + E_SY( S_ROTA, CHECK )
      IF E_IS_DOOR( R_MAP( CX, CY ) ) THEN
        REPEAT
        'STEP THROUGH USED MEMORY TO PREVENT MEMORY LEAKS.
        USED = INSTR( E_DOOR$, "U" )
        WHILE USED
          IF CX = E_DOORX( USED ) AND CY = E_DOORY( USED ) THEN GOTO E_UPDATE_CYCLE2
          USED = INSTR( E_DOOR$, "U", USED + 1 )
        WEND
        'SEARCH FOR FREE MEMORY.
        FREE = INSTR( E_DOOR$, "F" )
        IF FREE THEN
          E_DOORX( FREE ) = CX
          E_DOORY( FREE ) = CY
          VOLUME 0, 15,
          PLAY 0, 54, 60 SOUND 0
          'VBL INTERRUPT MIGHT OCCUR AFTER THIS LINE (BEFORE SIGNAL ON NEXT LINE).
          E_DOORT( FREE ) = TIMER
          'RECORD USED MEMORY. THIS ALSO SIGNALS THE VBL INTERRUPT, SO MUST OCCUR LAST.
          MID$( E_DOOR$, FREE, 1 ) = "U"
        END IF
        UNTIL 1
      ELSE IF E_MAP( CX, CY ) AND $2000 THEN
        REPEAT
        'STEP THROUGH USED MEMORY TO PREVENT MEMORY LEAKS.
        USED = INSTR( E_HIDE$, "U" )
        WHILE USED
          IF CX = E_HIDEX( USED, 0 ) AND CY = E_HIDEY( USED, 0 ) THEN GOTO E_UPDATE_CYCLE2
          USED = INSTR( E_HIDE$, "U", USED + 1 )
        WEND
        'SEARCH FOR FREE MEMORY.
        FREE = INSTR( E_HIDE$, "F" )
        IF FREE THEN
          'PREVENT ANY SUBSEQUENT PRESSES OF THE HIDDEN PANEL.
          E_MAP( CX, CY ) = E_MAP( CX, CY ) XOR $2000
          'SHOW HIDDEN PANEL'S AREA, IF ANY.
          FOR A1 = 0 TO E_AREA_HI
            IF CX = E_AREAX( A1 ) AND CY = E_AREAY( A1 ) THEN
              FOR R1 = E_AREA2INDEX( A1, 0 ) TO E_AREA2INDEX( A1, 1 )
                CALL S_MAP_LOAD( E_U(R1,0), E_U(R1,1), E_U(R1,2), E_U(R1,3), -1, E_U(R1,4) )
              NEXT R1
              EXIT
            END IF
          NEXT A1
          INC S_REDRAW_MAP
          CALL S_MAP
          'SET INITIAL LOCATION OF HIDDEN PANEL.
          E_HIDEX( FREE, 0 ) = CX
          E_HIDEY( FREE, 0 ) = CY
          'CALC DIRECTION VIA ATTRIBUTES. $00 INC X, $08 DEC X, $10 INC Y, $18 DEC Y.
          IF E_MAP( CX, CY ) AND $0800 THEN SIGN = -1 ELSE SIGN = 1
          IF E_MAP( CX, CY ) AND $1000 THEN
            SX = 0
            SY = SIGN
          ELSE
            SX = SIGN
            SY = 0
          END IF
          'SET SUBSEQUENT LOCATIONS OF HIDDEN PANEL.
          E_HIDEX( FREE, 1 ) = CX + SX
          E_HIDEY( FREE, 1 ) = CY + SY
          E_HIDEX( FREE, 2 ) = CX + SX * 2
          E_HIDEY( FREE, 2 ) = CY + SY * 2
          VOLUME 2, 15,
          PLAY 2, 30, 120 SOUND 0
          'VBL INTERRUPT MIGHT OCCUR AFTER THIS LINE (BEFORE SIGNAL ON NEXT LINE).
          E_HIDET( FREE ) = TIMER
          'RECORD USED MEMORY. THIS ALSO SIGNALS THE VBL INTERRUPT, SO MUST OCCUR LAST.
          MID$( E_HIDE$, FREE, 1 ) = "U"
        END IF
        UNTIL 1
      ELSE IF E_IS_BOOL( R_MAP( CX, CY ) ) THEN
        
      END IF
    E_UPDATE_CYCLE2:
    NEXT CHECK
  END IF
END SUB
SUB R_LOAD
  'CALL R_LOAD BEFORE CALL M_INIT (INIT PLAYER ROTATION BEFORE ROTATING).
  FOR CY = 0 TO 63
    FOR CX = 0 TO 63
      WORD = E_MAP( CX, CY )
      TILE0 = WORD MOD $100
      IF TILE0 = 130 OR TILE0 = 131 THEN
        IF TILE0 = 130 THEN
          FLIP_FX = WORD AND $0800
          IF FLIP_FX THEN DEGREES = 180 ELSE DEGREES = 0
        ELSE
          FLIP_FY = WORD AND $1000
          IF FLIP_FY THEN DEGREES = 270 ELSE DEGREES = 90
        END IF
        R_LOCX = CX + 0.5
        R_LOCY = CY + 0.5
        R_ROTA = DEGREES * PI / 180
        TILE0 = 0
      ELSE IF TILE0 = 132 OR TILE0 = 146 THEN
        TILE0 = 0
      END IF
      R_MAP( CX, CY ) = TILE0
    NEXT CX
  NEXT CY
END SUB
SUB R_INIT
  FOV = 90 * PI / 180
  'SCREENM DEFINED IN COMMENTS AT END OF FILE BEFORE ROMS.
  SCREENM  = TAN( FOV / 2 ) * 1.0 * 2
  'THUS SCREENM IS THE WIDTH-IN-BOXES OF THE SCREEN, AT A DISTANCE OF 1.0 BOX.
  BOX_PXL_WIDTH = 160 / SCREENM
  BOX_PXL_HEIGHT = BOX_PXL_WIDTH
  R_SCREENM5 = SCREENM * 0.5
  R_BOXHEIGHT5 = BOX_PXL_HEIGHT * 0.5
  R_SIDE1:
  DATA 1
  R_SIDE0:
  DATA 0
END SUB
SUB R_UPDATE
  R_LOC_IN_DOOR    = E_IS_DOOR( R_MAP( R_LOCX, R_LOCY ) )
  R_TILE_DOOR_JAMB =            R_MAP( R_LOCX, R_LOCY )   + 48
  R_RAYX = R_ROTX - R_ROTY * R_SCREENM5
  R_RAYY = R_ROTY + R_ROTX * R_SCREENM5
  IF E_INTERLEAVE THEN
    BX1 =  0
    BX2 = 19
  ELSE
    ADD R_RAYX, 20 * R_DSCREENX
    ADD R_RAYY, 20 * R_DSCREENY
    BX1 = 20
    BX2 = 39
  END IF
  FOR B_BX0 = BX1 TO BX2
    CALL R_MAIN_CALC
    R_MAPXS( B_BX0 ) = R_MAPX
    R_MAPYS( B_BX0 ) = R_MAPY
    R_TILES( B_BX0 ) = R_TILE
    R_SIDES( B_BX0 ) = R_SIDE
    R_RAYMS( B_BX0 ) = R_RAYM
    R_WALLS( B_BX0 ) = INT( B_PCT2TX * R_WALL )
    ADD R_RAYX, R_DSCREENX
    ADD R_RAYY, R_DSCREENY
  NEXT B_BX0
END SUB
SUB R_MAIN_CALC
  CALL R_INIT_MAPXY
  IF R_LOC_IN_DOOR THEN
    'CAST ONCE.
    CALL R_INC_MAPXY_SIDE
    'IF RAY HIT DOOR JAM THEN CALC AND EXIT.
    IF R_MAP( R_MAPX, R_MAPY ) THEN
      R_TILE = R_TILE_DOOR_JAMB
      CALL R_CALC_RAYM_WALL
      EXIT SUB
    END IF
    '(PROCEED ASSUMING RAY EXITED DOOR JAM, DROP INTO DO-LOOP.)
  END IF
  DO
    R_MAIN_CALC_CYCLE:
    'CAST ANY LENGTH.
    CALL R_REPEAT_MAPXY_SIDE
    R_TILE = R_MAP( R_MAPX, R_MAPY )
    'IF TILE IS PLAIN (NOT A DOOR) AND AN INT (NOT A HIDDEN PANEL), THEN CALC AND EXIT.
    IF E_IS_PLAIN( R_TILE ) THEN
      IF R_TILE = INT( R_TILE ) THEN
        CALL R_CALC_RAYM_WALL
        EXIT SUB
      END IF
      '(PROCEED ASSUMING TILE IS PLAIN, BUT ALSO A HIDDEN PANEL.) CAST INTO SEMI-PLANE.
      E_PCT_FLUSH0 = R_TILE - INT( R_TILE )
      E_PCT_FLUSH1 = 1 - E_PCT_FLUSH0
      'BACKUP VARIABLES, AS R_SEMI_MAPXY_SIDE'S CONVOLUTION PRECLUDES CALCULATION LATER.
      SIDE0 = R_SIDE
      TILE0 = R_TILE
      CALL R_SEMI_MAPXY_SIDE
      'IF RAY HIT SEMI-PLANE, RESTORE TILE*. IF RAY HIT DOOR JAMB, UPDATE TILE*. PRESUME RAY EXITED DOOR JAMB, CAST OUT OF SEMI-PLANE.
      IF SIDE0 = R_SIDE THEN R_TILE = TILE0 ELSE IF R_MAP( R_MAPX, R_MAPY ) THEN R_TILE = R_MAP( R_MAPX, R_MAPY ) ELSE GOTO R_MAIN_CALC_CYCLE
      'NOTE (*) ALSO CALC AND EXIT.
      CALL R_CALC_RAYM_WALL
      EXIT SUB
    END IF
    '(PROCEED ASSUMING TILE IS DOOR.) CAST INTO SEMI-PLANE.
    E_PCT_FLUSH0 = 0.50
    E_PCT_FLUSH1 = 0.50
    'PRECALCULATE PCT_OPEN, R_SEMI_MAPXY_SIDE'S CONVOLUTION PRECLUDES CALCULATION LATER.
    PCT_OPEN = 1.0 - M_MAP( R_MAPX, R_MAPY )
    CALL R_SEMI_MAPXY_SIDE
    'IF RAY HIT DOOR JAMB THEN CALC AND EXIT.
    IF R_SIDE <> R_TILE MOD 2 THEN
      'BOTH SIDE=0, TILE MOD 2=0 IMPLY RAY HIT X AXIS, I.E. A VERTICAL AXIS INTERCEPT.
      ADD R_TILE, 48
      'BOTH SIDE=1, TILE MOD 2=1 IMPLY RAY HIT Y AXIS, I.E. A HORIZONTAL AXIS INTERCEPT.
      CALL R_CALC_RAYM_WALL
      EXIT SUB
    END IF
    '(PROCEED ASSUMING RAY HIT SEMI-PLANE.) IF RAY HIT DOOR (ITSELF) THEN CALC AND EXIT.
    CALL R_CALC_RAYM_WALL
    IF R_WALL >= PCT_OPEN THEN
      ADD R_WALL, -PCT_OPEN
      EXIT SUB
    END IF
    '(PROCEED ASSUMING RAY HIT OPENING.) CAST OUT OF SEMI-PLANE.
    CALL R_SEMI_MAPXY_SIDE
    'IF RAY HIT DOOR JAMB THEN CALC AND EXIT. (SAME AS ABOVE.)
    IF R_SIDE <> R_TILE MOD 2 THEN
      ADD R_TILE, 48
      CALL R_CALC_RAYM_WALL
      EXIT SUB
    END IF
    '(PROCEED ASSUMING RAY EXITED DOOR JAM, LOOP.)
  LOOP
END SUB
SUB R_INIT_MAPXY
  R_MAPX = INT( R_LOCX )
  R_MAPY = INT( R_LOCY )
  IF R_RAYX > 0 THEN R_SX = (R_MAPX-R_LOCX+1)/R_RAYX ELSE IF R_RAYX THEN R_SX = (R_MAPX-R_LOCX)/R_RAYX ELSE R_SX = 999999
  IF R_RAYY > 0 THEN R_SY = (R_MAPY-R_LOCY+1)/R_RAYY ELSE IF R_RAYY THEN R_SY = (R_MAPY-R_LOCY)/R_RAYY ELSE R_SY = 999999
  R_DMAPX = SGN( R_RAYX )
  R_DMAPY = SGN( R_RAYY )
  IF R_RAYX THEN R_DSX = R_DMAPX / R_RAYX
  IF R_RAYY THEN R_DSY = R_DMAPY / R_RAYY
END SUB
SUB R_REPEAT_MAPXY_SIDE
  REPEAT
    IF R_SX < R_SY THEN
      ADD R_MAPX, R_DMAPX
      ADD R_SX, R_DSX
      RESTORE R_SIDE0
    ELSE
      ADD R_MAPY, R_DMAPY
      ADD R_SY, R_DSY
      RESTORE R_SIDE1
    END IF
  UNTIL R_MAP( R_MAPX, R_MAPY )
  READ R_SIDE
END SUB
SUB R_INC_MAPXY_SIDE
  IF R_SX < R_SY THEN
    ADD R_MAPX, R_DMAPX
    ADD R_SX, R_DSX
    RESTORE R_SIDE0
  ELSE
    ADD R_MAPY, R_DMAPY
    ADD R_SY, R_DSY
    RESTORE R_SIDE1
  END IF
  READ R_SIDE
END SUB
SUB R_SEMI_MAPXY_SIDE
  'CONVOLUTED DUE TO INTEGER ROUNDING (+1/-1) WITHIN R_CALC_RAYM_WALL.
  IF R_SIDE = 0 THEN
    IF R_SX - R_DSX * E_PCT_FLUSH0 < R_SY THEN
      'RAY HIT SEMI-PLANE (OLD SIDE = NEW SIDE).
      ADD R_MAPX, R_DMAPX * E_PCT_FLUSH1
      ADD R_SX, R_DSX * E_PCT_FLUSH1
      R_SIDE = 0
    ELSE
      'RAY HIT DOOR JAMB (OLD SIDE <> NEW SIDE).
      ADD R_MAPY, R_DMAPY
      ADD R_SY, R_DSY
      R_SIDE = 1
    END IF
  ELSE
    IF R_SX < R_SY - R_DSY * E_PCT_FLUSH0 THEN
      'RAY HIT DOOR JAMB (OLD SIDE <> NEW SIDE).
      ADD R_MAPX, R_DMAPX
      ADD R_SX, R_DSX
      R_SIDE = 0
    ELSE
      'RAY HIT SEMI-PLANE (OLD SIDE = NEW SIDE).
      ADD R_MAPY, R_DMAPY * E_PCT_FLUSH1
      ADD R_SY, R_DSY * E_PCT_FLUSH1
      R_SIDE = 1
    END IF
  END IF
END SUB
SUB R_CALC_RAYM_WALL
  'THE MAX INSTRUCTION ALLOWS STRAFE=0 AND ILL-DEFINED TILES (EX. DOORS) IN SUB R_UPDATE.
  IF R_SIDE THEN
    'THE MAX INSTRUCITON AVOIDS CRASHING, BUT GRAPHIC ARTIFACTS OCCUR.
    IF R_RAYY < 0 THEN
      'IF CRASHING OCCURS, THEN REPLACE "=" WITH "=MAX(0.0001," AND APPEND SUFFIX ")".
      R_RAYM = ( R_MAPY - R_LOCY + 1 ) / R_RAYY
      R_WALL = R_LOCX + R_RAYM * R_RAYX
      R_WALL = 1 - ( INT( R_WALL ) - R_WALL + 1 )
    ELSE
      'HERE TOO.
      R_RAYM = ( R_MAPY - R_LOCY ) / R_RAYY
      R_WALL = R_LOCX + R_RAYM * R_RAYX
      ADD R_WALL, -INT( R_WALL )
    END IF
  ELSE
    IF R_RAYX < 0 THEN
      'HERE TOO.
      R_RAYM = ( R_MAPX - R_LOCX + 1 ) / R_RAYX
      R_WALL = R_LOCY + R_RAYM * R_RAYY
      R_WALL = 1 - ( R_WALL - INT( R_WALL ) )
    ELSE
      'HERE TOO. FOUR LINES WOULD BE MODIFIED IN TOTAL.
      R_RAYM = ( R_MAPX - R_LOCX ) / R_RAYX
      R_WALL = R_LOCY + R_RAYM * R_RAYY
      R_WALL = INT( R_WALL ) - R_WALL + 1
    END IF
  END IF
END SUB
SUB B_LOAD_TILES
  RESTORE B_LOAD_TILES0
  B_LOAD_TILES0:
  'TILE2TEX, SEE GFX DESIGNER PAGE THREE AND ROM 4-5 136  137  138  139  140  141  142  143
  DATA        -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   1,   1,   1,   1,   2,   2
  'TILE2TEX (DON'T USE LEFT-HALF OF PAGE THREE)      152  153  154  155  156  157  158  159
  DATA        -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   3,   4,   8,   6,   7,  11,   5,   6
  'TILE2TEX                                          168  169  170  171  172  173  174  175
  DATA        -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   7,  12,  13,  14,   0,   0,   0,   0
  'TILE2TEX                                          184  185  186  187  188  189  190  191
  DATA        -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  15,  15,  15,  15,  15,  15,  15,  15
  'TILE2CLR SIDE0 136       137       138       139       140       141       142       143
  DATA        $2F1B01,       -1,  $001501,       -1,  $153F01,       -1,  $202A00,       -1
  'TILE2CLR SIDE0 152       153       154       155       156       157       158       159
  DATA        $2A1702,  $2A1702,  $3F2A15,  $3E2A20,  $392F15,  $3D2A20,  $3E3824,  $3F2A20
  'TILE2CLR SIDE0 168       169       170       171       172       173       174       175
  DATA        $3F2015,  $382A01,  $3E2A20,  $3E2A20,       -2,       -2,       -2,       -2
  'TILE2CLR SIDE0 184       185       186       187       188       189       190       191
  DATA             -1,  $2F1A01,       -1,  $291401,       -1,  $291401,       -1,  $101500
  'TILE2CLR SIDE1 136       137       138       139       140       141       142       143
  DATA             -1,  $2F1B01,       -1,  $001501,       -1,  $153F01,       -1,  $202A00
  'TILE2CLR SIDE1 152       153       154       155       156       157       158       159
  DATA        $2A1602,  $2A1602,  $2A1500,  $291510,  $241A00,  $291510,  $292410,  $2A1510
  'TILE2CLR SIDE1 168       169       170       171       172       173       174       175
  DATA        $2A1000,  $241500,  $291510,  $291510,       -2,       -2,       -2,       -2
  'TILE2CLR SIDE1 184       185       186       187       188       189       190       191
  DATA        $2F1A01,       -1,  $291401,       -1,  $291401,       -1,  $101500,       -1
  FOR TILE = 128 TO 191
    READ B_TILE2TEX( TILE )
  NEXT TILE
  FOR TILE = 128 TO 191
    IF B_TILE2TEX( TILE ) >= 0 THEN READ B_TILE2CLR( TILE, 0 )
  NEXT TILE
  FOR TILE = 128 TO 191
    IF B_TILE2TEX( TILE ) >= 0 THEN READ B_TILE2CLR( TILE, 1 )
  NEXT TILE
  B_PAL2CLR( 0 ) = $3F2A15
  B_PAL2CLR( 7 ) = $2F1A01
  POKEL $FF01, B_PAL2CLR( 0 )
  POKE  $FF1D, B_PAL2CLR( 7 )
  POKE  $FF1E, B_PAL2CLR( 7 ) \ $100
  POKE  $FF1F, B_PAL2CLR( 7 ) \ $10000
  'INIT (UNCOMMENT) TO SHOW FAST FILL FLOOR AND CEILING. B_CEILING=63, B_FLOOR=21.
END SUB
SUB B_LOAD_TEX( SRC, TEX1, TEX2, TEX_SIZE )
  DIM MASK( 7 ), MULT2( 1 ), MULT04( 3 ), MULT16( 3 )
  MASK( 0 ) = $80
  MASK( 1 ) = $40
  MASK( 2 ) = $20
  MASK( 3 ) = $10
  MASK( 4 ) = $08
  MASK( 5 ) = $04
  MASK( 6 ) = $02
  MASK( 7 ) = $01
  MULT2( 1 ) = 2
  FOR CLR = 1 TO 3
    MULT04( CLR ) =  4 * CLR
    MULT16( CLR ) = 16 * CLR
  NEXT CLR
  IF TEX_SIZE = 0 THEN
    M2 = 15
    XX =  0
  ELSE IF TEX_SIZE = 1 THEN
    M2 =  7
    XX =  1
  END IF
  C2         = 8 * XX
  LEFT2DOWN1 = ( -$20 + $100 ) * XX
  RIGHT2UP2  = (  $20 - $200 ) * XX
  DOWN1      = (        $100 ) * XX
  FOR MY = 0 TO M2
    FOR MX = 0 TO M2
      FOR CY = 0 TO C2 STEP 8
        FOR CX = 0 TO C2 STEP 8
          FOR PY = 0 TO 7
            TY = CY + PY
            VAL0 = PEEK( SRC )
            VAL8 = PEEK( SRC + 8 )
            FOR PX = 0 TO 7
              TX = CX + PX
              CLR = SGN( VAL0 AND MASK( PX ) ) + MULT2( SGN( VAL8 AND MASK( PX ) ) )
              B_TY0_2CH( TEX1, TX, TY ) =         CLR
              B_TY1_2CH( TEX1, TX, TY ) = MULT04( CLR )
              B_TY2_2CH( TEX1, TX, TY ) = MULT16( CLR )
            NEXT PX
            INC SRC
          NEXT PY
          ADD SRC, 8
        NEXT CX
        ADD SRC, LEFT2DOWN1
      NEXT CY
      IF TEX1 = TEX2 THEN EXIT SUB
      INC TEX1
      ADD SRC, RIGHT2UP2
    NEXT MX
    ADD SRC, DOWN1
  NEXT MY
END SUB
SUB B_UPDATE
  CALL B_PALETTES
  IF E_INTERLEAVE THEN
    B_BX0 = 0
    B_CX = 0
    CX2  = 9
  ELSE
    B_BX0 = 20
    B_CX = 10
    CX2  = 19
  END IF
  BG 0
  CALL B_SHOW
  CALL B_EVAL( 1 )
  FOR B_CX = B_CX + 1 TO CX2
    CALL B_EVAL( 0 )
    CALL B_EVAL( 1 )
  NEXT B_CX
END SUB
SUB B_PALETTES
  'TWO-PASSES, COLORS KEEP SAME PALETTES BETWEEN COLUMN DRAWS.
  DIM PAL2SUM( 7 )
  'FIRST PASS.
  FOR B_BX0 = 0 TO 39
    BXCLR = B_TILE2CLR( R_TILES( B_BX0 ), R_SIDES( B_BX0 ) )
    FOR PL0 = 0 TO 7
      IF B_PAL2CLR( PL0 ) = BXCLR THEN
        'ASSIGN PALETTE.
        B_BX2PAL( B_BX0 ) = PL0
        INC PAL2SUM( PL0 )
        GOTO B_PAL_PASS1_CYCLE2
      END IF
    NEXT PL0
    'ASSIGN NO PALETTE.
    B_BX2PAL( B_BX0 ) = 8
    B_PAL_PASS1_CYCLE2:
  NEXT B_BX0
  'SECOND PASS, IF NO PALETTE ASSIGNED.
  FOR B_BX0 = 0 TO 39
    IF B_BX2PAL( B_BX0 ) = 8 THEN
      BXCLR = B_TILE2CLR( R_TILES( B_BX0 ), R_SIDES( B_BX0 ) )
      FOR PL0 = 1 TO 6
        IF B_PAL2CLR( PL0 ) = BXCLR THEN
          'ASSIGN PALETTE. CHECKED AGAIN AS PAL 1 TO 6 COULD CHANGE.
          B_BX2PAL( B_BX0 ) = PL0
          INC PAL2SUM( PL0 )
          GOTO B_PAL_PASS2_CYCLE2
        END IF
      NEXT PL0
      FOR PL0 = 1 TO 6
        IF PAL2SUM( PL0 ) = 0 THEN
          'ASSIGN NEXT PALETTE.
          B_PAL2CLR( PL0 ) = BXCLR
          B_BX2PAL( B_BX0 ) = PL0
          INC PAL2SUM( PL0 )
          GOTO B_PAL_PASS2_CYCLE2
        END IF
      NEXT PL0
      'ASSIGN DEFAULT PALETTE.
      B_BX2PAL( B_BX0 ) = 0
    END IF
    B_PAL_PASS2_CYCLE2:
  NEXT B_BX0
  'REFRESH ALL PALETTES.
  POKEL $FF05, B_PAL2CLR( 1 )
  POKEL $FF09, B_PAL2CLR( 2 )
  POKEL $FF0D, B_PAL2CLR( 3 )
  POKEL $FF11, B_PAL2CLR( 4 )
  POKEL $FF15, B_PAL2CLR( 5 )
  POKEL $FF19, B_PAL2CLR( 6 )
END SUB
SUB B_EVAL( BKGRND )
  BG BKGRND
  'SHORT-CIRCULT EVALUATION AND JOHN CARMACK'S "DEFERRED" COLUMN RENDERING.
  IF R_RAYMS(B_BX0)<B_RAY0 THEN IF R_MAPXS(B_BX0-1)=R_MAPXS(B_BX0) AND R_MAPYS(B_BX0-1)=R_MAPYS(B_BX0) AND R_SIDES(B_BX0-1)=R_SIDES(B_BX0) AND R_WALLS(B_BX0-1)=R_WALLS(B_BX0) THEN CALL B_COPY(BKGRND) ELSE CALL B_SHOW
END SUB
SUB B_COPY( BKGRND )
  BG SOURCE $9800 - $800 * BKGRND, 32, 32
  'UNCOMMENT 'BG FILL' SHOWS "DEFERRED COLUMN RENDER".
  BG COPY B_CX + BKGRND - 1, 0, 1, 32 TO B_CX, 0
  'BG FILL B_CX, 0 TO B_CX, 31 CHAR 57
  INC B_BX0
END SUB
SUB B_SHOW
  PAL B_BX2PAL( B_BX0 )
  '(B_TX0,B_TY0)=TEXTURE, B_TY#_2CH=ROW #, (B_BX0,BY0)=BLOCK, BY1=HI, (R_CX,CY0)=CELL, CY1=HI.
  B_TEXNUM = B_TILE2TEX( R_TILES( B_BX0 ) )
  B_TX0 = R_WALLS( B_BX0 )
  FOR CODE_WRAP = 1 TO 0
    'BREATHING WALLS.
    TIME_FREQ      = 300
    TIME_PERIOD    = SIN( 2 * PI / TIME_FREQ * TIMER )
    SPACE_PERIOD   = SIN( PI / B_PCT2TX * B_TX0 )
    AMPLITUDE      = 20
    OFFSET         = AMPLITUDE * TIME_PERIOD * SPACE_PERIOD
    LINEHEIGHT5    = ( R_BOXHEIGHT5 + OFFSET ) / R_RAYMS( B_BX0 )
  NEXT CODE_WRAP
  FOR CODE_WRAP = 1 TO 1
    LINEHEIGHT5 = R_BOXHEIGHT5 / R_RAYMS( B_BX0 )
  NEXT CODE_WRAP
  FOR CODE_WRAP = 1 TO 0
    'BLOOD OCEAN. DON'T GO HIGHER THAN HORIZON.
    CYCLE          = SIN( 2 * PI / B_PCT2TX * ( B_TX0 - TIMER / 5 ) )
    AMPLITUDE      = 3
    OFFSET         = AMPLITUDE * ( CYCLE + 1 )
    BY0            = MAX( 48 - LINEHEIGHT5, 0 ) 
    BY1            = MIN( 47 + LINEHEIGHT5, 95 ) - OFFSET / R_RAYMS( B_BX0 )
  NEXT CODE_WRAP
  FOR CODE_WRAP = 1 TO 1
    BY0 = MAX( 48 - LINEHEIGHT5, 0 )
    BY1 = MIN( 47 + LINEHEIGHT5, 95 )
  NEXT CODE_WRAP
  B_DTY = B_PCT2TY / LINEHEIGHT5
  B_TY0 = ( BY0 - 47.999 + LINEHEIGHT5 ) * B_DTY
  CY0 = BY0 \ 3
  IF CY0 THEN BG FILL B_CX, 0 TO B_CX, CY0 - 1 CHAR B_CEILING
  IF BY0 MOD 3 = 2 THEN
    CALL B_ADD(    0, B_TY2_2CH() )
    CELL B_CX, CY0, B_CH
    INC CY0
  ELSE IF BY0 MOD 3 THEN
    CALL B_ADD(    0, B_TY1_2CH() )
    CALL B_ADD( B_CH, B_TY2_2CH() )
    CELL B_CX, CY0, B_CH
    INC CY0
  END IF
  CY1 = BY1 \ 3 - 1
  FOR CY0 = CY0 TO CY1
    CALL B_ADD(    0, B_TY0_2CH() )
    CALL B_ADD( B_CH, B_TY1_2CH() )
    CALL B_ADD( B_CH, B_TY2_2CH() )
    CELL B_CX, CY0, B_CH
  NEXT CY0
  IF BY1 MOD 3 = 2 THEN
    CALL B_ADD(    0, B_TY0_2CH() )
    CALL B_ADD( B_CH, B_TY1_2CH() )
    CALL B_ADD( B_CH, B_TY2_2CH() )
    CELL B_CX, CY0, B_CH
  ELSE IF BY1 MOD 3 THEN
    CALL B_ADD(    0, B_TY0_2CH() )
    CALL B_ADD( B_CH, B_TY1_2CH() )
    CELL B_CX, CY0, B_CH
  ELSE
    CALL B_ADD(    0, B_TY0_2CH() )
    CELL B_CX, CY0, B_CH
  END IF
  IF CY0 < 31 THEN BG FILL B_CX, CY0 + 1 TO B_CX, 31 CHAR B_FLOOR
  INC B_BX0
END SUB
SUB B_ADD( CH0, LOOKUP() )
  B_CH = CH0 + LOOKUP( B_TEXNUM, B_TX0, MIN( B_TY0, 15 ) )
  ADD B_TY0, B_DTY
END SUB
SUB M_LOAD
  FOR CY = 0 TO 63
    FOR CX = 0 TO 63
      TILE0 = E_MAP( CX, CY ) MOD $100
      IF TILE0  = 130  OR TILE0 = 131 THEN TILE0 = 0
      IF TILE0  = 132  OR TILE0 = 146 THEN TILE0 = 0
      M_MAP( CX, CY ) = SGN( TILE0 )
    NEXT CX
  NEXT CY
END SUB
SUB M_INIT
  GAMEPAD 1
  'CALL R_LOAD BEFORE CALL M_INIT (INIT PLAYER ROTATION BEFORE ROTATING).
  PAUSE OFF
  'DEFINE RUNNING INCREMENTS. STRAFE MUST BE NON-ZERO (AVOID BACK-TO-WALL-180-CLIP).
  M_FWD0 =  0.130
  M_ROT0 =  3.750 * PI / 180
  M_STR0 =  0.001
  'DEFINE AIMING INCREMENTS. STRAFE MUST BE NON-ZERO (AVOID BACK-TO-WALL-180-CLIP).
  M_STR1 =  0.050
  'DEFINE CLIPPING COLLISION DIAMOND/CYLINDER RADIUS. <LOC> IS A POINT ON THIS CIRCLE'S RAD.
  M_RAD1 =  0.075
  'RAD2 IS A BUFFER RADIUS, CENTERED ON SAME CIRCLE AS ABOVE. MUST BE NON-ZERO (AVOID DOOR HASTY RENDER).
  M_RAD2 =  0.125
  'DIVIDE INCREMENTS FOR USE LATER WITH M_INPUT LOOP.
  FOR M_ITER = 1 TO 10
    'STILL NOT SURE WHAT FRACTION TO USE HERE, CALC WITH 95% FOR NOW.
    IF SQR( (M_FWD0/M_ITER)^2 + (M_STR0/M_ITER)^2 ) < 0.95 * M_RAD1 THEN EXIT
  NEXT M_ITER
  M_FWD0 = M_FWD0 / M_ITER
  M_STR0 = M_STR0 / M_ITER
  M_STR1 = M_STR1 / M_ITER
  'SET PLAYER ROTATION (SUB R_LOAD SETS R_ROTA, R_LOCX, AND R_LOCY).
  CALL M_CALC_ROT( 0 )
END SUB
SUB M_INPUT
  TURN = RIGHT( 0 ) - LEFT( 0 )
  ROT = TURN * M_ROT0
  IF E_HOLD_B_FRAMES THEN STR = TURN * M_STR1 ELSE STR = TURN * M_STR0
  MOVE = DOWN( 0 ) - UP( 0 )
  FWD = MOVE * M_FWD0
  IF ROT THEN CALL M_CALC_ROT( ROT )
  IF SGN( FWD ) OR SGN( STR ) THEN
    FOR J = 1 TO M_ITER
      CALL M_CALC_TRN( FWD, STR )
    NEXT J
  END IF
  IF PAUSE THEN CALL M_PAUSE
END SUB
SUB M_CALC_TRN( FWD, STR )
  '<R_DMD>=<LOC>+<STEP>+M_RAD1*<<ROT>> (M_RAD1*<<ROT>> ALLOWS BACK-TO-WALL BUT NOT NOSE).
  DMDX = R_LOCX + ( FWD + M_RAD1 ) * R_ROTX + STR * R_ROTY
  'A DIAMOND ORIENTED ON BOX AXIS (NOT ORIENTED BY <<ROT>>) *IS* A CYLINDER.
  DMDY = R_LOCY + ( FWD + M_RAD1 ) * R_ROTY - STR * R_ROTX
  'DIAMOND <R_DMD>, SIZE 2*M_RAD1, LOCATION ROTATED ABOVE (ORIENTATION NOT ROTATED BELOW).
  IF M_MAP( DMDX + M_RAD2, DMDY ) THEN
    '(ABOVE) IF RIGHT HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT LEFTWARDS.
    R_LOCX = INT( DMDX + M_RAD2 )     - M_RAD2 - M_RAD1 * R_ROTX
  ELSE IF M_MAP( DMDX - M_RAD2, DMDY ) THEN
    '(ABOVE) IF LEFT HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT RIGHTWARDS.
    R_LOCX = INT( DMDX - M_RAD2 ) + 1 + M_RAD2 - M_RAD1 * R_ROTX
  ELSE
    'NO HIT, IN X, <LOC>=<LOC>+<STEP>.
    R_LOCX = DMDX - M_RAD1 * R_ROTX
  END IF
  IF M_MAP( DMDX, DMDY + M_RAD2 ) THEN
    '(ABOVE) IF UP HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT DOWNWARDS.
    R_LOCY = INT( DMDY + M_RAD2 )     - M_RAD2 - M_RAD1 * R_ROTY
  ELSE IF M_MAP( DMDX, DMDY - M_RAD2 ) THEN
    '(ABOVE) IF DOWN HITS THEN (BELOW) REVERSE FROM DIAMOND'S POINT UPWARDS.
    R_LOCY = INT( DMDY - M_RAD2 ) + 1 + M_RAD2 - M_RAD1 * R_ROTY
  ELSE
    'NO HIT, IN Y, <LOC>=<LOC>+<STEP>.
    R_LOCY = DMDY - M_RAD1 * R_ROTY
  END IF
  'I WOUL LOVE TO IMPELEMNT A "NOTCH" (JOHN CARMACK, IPHONE 2009) BUT CAN'T FIGURE IT OUT.
END SUB
SUB M_CALC_ROT( ROT )
  ADD R_ROTA, ROT
  ADD R_ROTA, 6.283185 * -INT( R_ROTA / 6.283185 )
  R_ROTX = COS( R_ROTA )
  R_ROTY = SIN( R_ROTA )
  'R_ROT * "UNITS ARE BOXES PER COLUMN" (40 COLUMNS COVERS HALF THE SCREEN).
  R_DSCREENX =  R_ROTY * R_SCREENM5 / 20
  R_DSCREENY = -R_ROTX * R_SCREENM5 / 20
END SUB
SUB M_PAUSE
  ADD M_PAUSE, 1, 1 TO 15
  FOR IS_OUT = -1 TO 0
    IF M_PAUSE =  1 THEN CALL T_FADE      ( IS_OUT      )
    IF M_PAUSE =  2 THEN CALL T_WIPE_CELL ( IS_OUT      )
    IF M_PAUSE =  3 THEN CALL T_WIPE_BLOCK( IS_OUT      )
    IF M_PAUSE =  4 THEN CALL T_DITHER    ( IS_OUT, $10 )
    IF M_PAUSE =  5 THEN CALL T_DITHER    ( IS_OUT, $2A )
    IF M_PAUSE =  6 THEN CALL T_DIFFUSE   ( IS_OUT, $10 )
    IF M_PAUSE =  7 THEN CALL T_DIFFUSE   ( IS_OUT, $2A )
    IF M_PAUSE =  8 THEN CALL T_COLR      ( IS_OUT, $03 )
    IF M_PAUSE =  9 THEN CALL T_COLR      ( IS_OUT, $0C )
    IF M_PAUSE = 10 THEN CALL T_COLR      ( IS_OUT, $0F )
    IF M_PAUSE = 11 THEN CALL T_COLR      ( IS_OUT, $30 )
    IF M_PAUSE = 12 THEN CALL T_COLR      ( IS_OUT, $33 )
    IF M_PAUSE = 13 THEN CALL T_COLR      ( IS_OUT, $3C )
    IF M_PAUSE = 14 THEN CALL T_COLR      ( IS_OUT, $15 )
    IF M_PAUSE = 15 THEN CALL T_COLR      ( IS_OUT, $2A )
    IF IS_OUT THEN
      FLUSH_PAUSE_QUEUE = PAUSE
      PAUSE
    END IF
  NEXT IS_OUT
END SUB
SUB I_INIT
  'CEILING,FLOOR PAIRS: -1 CEILING ONLY, $00, $01, $04, $05, $10, $11, $14, $15, $2A, $3F.
  CEILING_CLR = -1
  FLOOR_CLR = $11
  RESTORE I_INIT0
  I_INIT0:
  DATA %111111, %111111, %101111, %111111, %101111, %111111
  DATA %101111, %101111, %011111, %101111, %011111, %101111
  DATA %011111, %011111, %001111, %011111, %001111, %011111
  DATA %001111, %001111, %001011, %001111, %001011, %001111
  DATA %001011, %001011, %000111, %001011, %000111, %001011
  DATA %000111, %000111, %000010, %000111, %000010, %000111
  DATA %000010, %000010, %000001, %000010, %000001, %000010
  DATA %000001, %000001, %000000, %000001, %000000, %000001
  FOR RY = 0 TO 47
    IF CEILING_CLR = -1 THEN READ I_P0C0( RY ) ELSE I_P0C0( RY ) = CEILING_CLR
  NEXT RY
  FOR RY = 48 TO 95
    I_P0C0( RY ) = FLOOR_CLR
  NEXT RY
  SCROLLY = 0
  FOR RY = 0 TO 95 STEP 3
    I_BGY( RY     ) = SCROLLY
    I_BGY( RY + 1 ) = SCROLLY
    I_BGY( RY + 2 ) = SCROLLY
    ADD SCROLLY, 5
  NEXT RY
  FOR RY = 0 TO 127
    UNSIGNED = ( I_BGY( RY ) + $100 ) MOD $100
    '$FF22=BG0Y, $FF23=BG1X, $FF24=BG1Y, $FF25=MSB, $FF22=BG0Y+$100*BG1X+$10000*BG1Y, MSB=0.
    I_BGY( RY ) = UNSIGNED + $100*($100-4) + $10000*UNSIGNED
  NEXT RY
  I_JUMP(48)=1
  I_JUMP(95)=1
  RESTORE I_INIT1
  I_INIT1:
  DATA 0, 151, 167, 183, 183, 167, 151, 0
  TIME0 = 0
  FOR J = 1 TO 8
    READ CH
    FOR FRAME = 1 TO 32
      I_BEACON( TIME0 ) = CH
      INC TIME0
    NEXT FRAME
  NEXT J
  ON VBL CALL I_VBL
END SUB
SUB I_VBL
  ON RASTER CALL I_RASTER2
  SPRITE 0, , , I_BEACON( TIMER MOD 256 )
  'UPDATE DOORS. STEP THROUGH USED MEMORY.
  USED = INSTR( E_DOOR$, "U" )
  WHILE USED
    LAP = TIMER - ABS( E_DOORT( USED ) )
    IF E_DOORT( USED ) > 0 THEN
      M_MAP( E_DOORX( USED ), E_DOORY( USED ) ) = MAX( 0.0, 1.0 - LAP / 60.0      )
      IF LAP = 180 THEN E_DOORT( USED ) = 0
    ELSE IF E_DOORT( USED ) = 0 THEN
      DISTX = ABS(E_DOORX( USED )+0.5-R_LOCX)
      DISTY = ABS(E_DOORY( USED )+0.5-R_LOCY)
      FREE = DISTX > 0.75 OR DISTY > 0.75
      IF FREE THEN
        E_DOORT( USED ) = -TIMER
        FOR CODE_WRAP = 1 TO 0
          SPL1 = 48.0
          RAD1 = 1.25
          RAD2 = MAX( SQR( DISTX ^ 2 + DISTY ^ 2 ), RAD1 )
          'SOUND PRESSURE LEVEL (SPL) SOUND ATTENUATION FORMULA.
          SPL2 = SPL1 - 20 * LOG( RAD2 / RAD1 ) / LOG( 10 )
          'APPROXIMATE RELATIONSHIP BETWEEN SPL (UNITS DBA) AND CONSOLE'S VOLUME SETTINGS.
          VOL2 = 1.339 * SPL2 - 39.818
        NEXT CODE_WRAP
        FOR CODE_WRAP = 1 TO 1
          RAD = SQR( DISTX ^ 2 + DISTY ^ 2 )
          VOL2 = 15 - 1.5 * RAD
        NEXT CODE_WRAP
        PLAY 1, 54, 60 SOUND 0
      END IF
    ELSE IF E_DOORT( USED ) < 0 THEN
      M_MAP( E_DOORX( USED ), E_DOORY( USED ) ) = MIN(            LAP / 60.0, 1.0 )
      IF LAP = 60 THEN MID$( E_DOOR$, USED, 1 ) = "F"
    END IF
    USED = INSTR( E_DOOR$, "U", USED + 1 )
  WEND
  'UPDATE HIDDEN PANELS. STEP THROUGH USED MEMORY.
  USED = INSTR( E_HIDE$, "U" )
  WHILE USED
    IF E_HIDET( USED ) = INT( E_HIDET( USED ) ) THEN
      LAP = TIMER - ABS( E_HIDET( USED ) )
      IF E_HIDET( USED ) > 0 THEN
        POS = 0
        IF LAP = 59 THEN E_HIDET( USED ) = 0.3125
      ELSE
        POS = 1
        IF LAP = 59 THEN E_HIDET( USED ) = 0.6875
      END IF
      'UPDATE SEMI-PLANE.
      CX1 = E_HIDEX( USED, POS )
      CY1 = E_HIDEY( USED, POS )
      R_MAP( CX1, CY1 ) = INT( R_MAP( CX1, CY1 ) ) + MAX( 0.0, 1.0 - LAP / 60.0 )
      'UPDATE S_MAP.
      IF LAP = 30 THEN
        INC POS
        CX2 = E_HIDEX( USED, POS )
        CY2 = E_HIDEY( USED, POS )
        SWAP S_MAP( CX2 + 32, CY2 + 16 ), S_MAP( CX1 + 32, CY1 + 16 )
        INC S_REDRAW_MAP
      END IF
    ELSE
      'UPDATE MAPS.
      IF E_HIDET( USED ) = 0.3125 THEN
        CX1 = E_HIDEX( USED, 0 )
        CY1 = E_HIDEY( USED, 0 )
        CX2 = E_HIDEX( USED, 1 )
        CY2 = E_HIDEY( USED, 1 )
        E_HIDET( USED ) = -TIMER
      ELSE
        CX1 = E_HIDEX( USED, 1 )
        CY1 = E_HIDEY( USED, 1 )
        CX2 = E_HIDEX( USED, 2 )
        CY2 = E_HIDEY( USED, 2 )
        MID$( E_HIDE$, USED, 1 ) = "F"
      END IF
      SWAP E_MAP( CX2, CY2 ), E_MAP( CX1, CY1 )
      SWAP R_MAP( CX2, CY2 ), R_MAP( CX1, CY1 )
      R_MAP( CX2, CY2 ) = INT( R_MAP( CX2, CY2 ) )
      SWAP M_MAP( CX2, CY2 ), M_MAP( CX1, CY1 )
    END IF
    USED = INSTR( E_HIDE$, "U", USED + 1 )
  WEND
END SUB
SUB I_RASTER2
  POKEL $FF22, I_BGY( RASTER )
  PALETTE 0, I_P0C0( RASTER ), , ,
  IF I_JUMP( RASTER ) THEN ON RASTER CALL I_RASTER1
END SUB
SUB I_RASTER1
  POKEL $FF22, I_BGY( RASTER )
  IF I_JUMP( RASTER ) THEN ON RASTER OFF
END SUB
SUB S_LOAD
  RESTORE S_LOAD0
  'TILE2CLR, SEE GFX DESIGNER PAGE THREE
  S_LOAD0:
  'TILE2CLR, 128  129  130  131  132  133  134  135  136  137  138  139  140  141  142  143
  DATA         0,   0,   2,   2,   2,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
  'TILE2CLR  144  145  146  147  148  149  150  151  152  153  154  155  156  157  158  159
  DATA         0,   0,   2,   0,   0,   0,   0,   0,   1,   1,   1,   1,   1,   1,   1,   1
  'TILE2CLR  160  161  162  163  164  165  166  167  168  169  170  171  172  173  174  175
  DATA         0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   1,   1,   1,   1,   1,   1
  'TILE2CLR  176  177  178  179  180  181  182  183  184  185  186  187  188  189  190  191
  DATA         0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0
  S_TILE2CLR( 0 ) = 0
  FOR TILE0 = 128 TO 191
    READ S_TILE2CLR( TILE0 )
  NEXT TILE0
  CALL S_MAP_LOAD( 0, 0, 63, 63, $0300, 1 )
END SUB
SUB S_INIT
  RESTORE S_INIT0
  S_INIT0:
  '                         63 MIPMAP       62 MIPMAP       61 MIPMAP       60 MIPMAP     59 C1/C2/C3
  DATA                    0,0,192,$E0,    0,0,196,$E0,    0,0,200,$E0,    0,0,204,$E0,  0,0,0,$20,-15
  '         44 SX-LIB       38 MIPMAP       37 MIPMAP       36 MIPMAP       35 MIPMAP     34 C1/C2/C3
  DATA   0,0,0,$00,-6,    0,0,192,$E0,    0,0,196,$E0,    0,0,200,$E0,    0,0,204,$E0,  0,0,0,$20,-15
  '       19 HUD MASK     18 HUD MASK     17 HUD MASK     16 HUD MASK     15 HUD MASK     14 HUD MASK
  DATA    0,96,68,$E7,    0,96,68,$FF,   32,96,68,$E7,   32,96,68,$FF,   96,96,64,$E7,   96,96,64,$FF
  '       13 HUD MASK     12 HUD MASK        11 HEART       10 BULLET       9 NUMBERS
  DATA  128,96,64,$E7,  128,96,64,$FF,   2,96,128,$60,  2,112,160,$60,  21,96,130,$E0
  '     8 DARK KEY HI   7 DARK KEY LO   6 LITE KEY HI   5 LITE KEY LO       4 WEAPONS
  DATA  50,96,134,$20, 50,104,150,$20, 50,112,166,$20, 50,120,182,$20,   64,96,76,$E0
  '        3 MAP LEFT     2 MAP RIGHT    1 MAP AVATAR      0 MAP GOAL  
  DATA 100,98,136,$E0, 132,98,140,$E0,127,111,135,$20,      0,0,0,$20
  FOR SN = 63 TO 0 STEP -1
    READ UNION
    IF UNION >= 0 THEN
      PX = UNION
      READ PY, CH, ATR
      SPRITE SN, PX, PY, CH
      SPRITE.A SN, ATR
    ELSE
      FOR ITER = UNION + 2 TO 0
        SPRITE SN, PX, PY, CH
        SPRITE.A SN, ATR
        DEC SN
      NEXT ITER
      INC SN
    END IF
  NEXT SN
  DATA 1, 2, 3, 9, 35, 36, 37, 38, 60, 61, 62, 63
  REPEAT
    READ SN
    CALL S_WIPE( SN )
  UNTIL SN = 63
  'CALCULATE LOOKUP BITMAPS AND ADDRESSES FOR LEFT AND RIGHT MAP SPRITES.
  DATA $0000, $0000, $0000, $0000, $0000, $0000, $0000, $0000
  DATA $0080, $0040, $0020, $0010, $0008, $0004, $0002, $0001
  DATA $8000, $4000, $2000, $1000, $0800, $0400, $0200, $0100
  DATA $8080, $4040, $2020, $1010, $0808, $0404, $0202, $0101
  FOR CLR = 0 TO 3
    READ S_8080(CLR), S_4040(CLR), S_2020(CLR), S_1010(CLR)
    READ S_0808(CLR), S_0404(CLR), S_0202(CLR), S_0101(CLR)
  NEXT CLR
  CX0 = 0
  FOR MAP_SN = 3 TO 2 STEP -1
    ADR = $8000 + 16 * SPRITE.C( MAP_SN )
    FOR CY0 = 0 TO 24 STEP 8
      FOR CX1 = CX0 TO CX0 + 3
        FOR PY0 = 0 TO 7
          PY1 = CY0 + PY0
          S_ADR0( CX1, PY1 ) = ADR
          S_ADR8( CX1, PY1 ) = ADR + 8
          INC ADR
        NEXT PY0
        ADD ADR, 8
      NEXT CX1
      ADD ADR, $100 - $40
    NEXT CY0
    ADD CX0, 4
  NEXT MAP_SN
  'SIGNAL TO S_AVATAR TO FORCE UPDATE.
  S_ROTA = -1
  'RESET S_MAP.
  S_LOCX = 0
  S_LOCY = 0
END SUB
SUB S_WIPE( SN )
  CH = 16 * SPRITE.C( SN )
  PSZ = SPRITE.A( SN ) \ 64 * 8
  FOR CY = 0 TO PSZ STEP 8
    FOR CX = 0 TO PSZ STEP 8
      FILL 32 * CY + 2 * CX + CH + $8000, 16
    NEXT CX
  NEXT CY
END SUB
SUB S_UPDATE
  CALL S_MAP
  CALL S_HEART
  CALL S_BULLET
  CALL S_AVATAR
END SUB
SUB S_HEART
  NUM = INT( 100 * R_LOCX + 0.5 )
  IF S_HLTH <> NUM THEN
    S_HLTH = NUM
    CALL S_NUMBER( 3, S_HLTH )
  END IF
END SUB
SUB S_BULLET
  NUM = INT( 100 * R_LOCY + 0.5 )
  IF S_AMMO <> NUM THEN
    S_AMMO = NUM
    CALL S_NUMBER( 19, S_AMMO )
  END IF
END SUB
SUB S_NUMBER( PY0, NUM )
  T$ = STR$( INT( MIN( MAX( 0, NUM ), 9999 ) ) )
  T$ = LEFT$( "  ", 3 - MIN( LEN( T$ ), 3 ) ) + T$ + " "
  SRC0 = ROM( 2 ) + 16 * 196
  SRC8 = SRC0 + 8
  NUMBERS_SN = 9
  DST0 = $8000 + 16 * SPRITE.C( NUMBERS_SN ) + PY0 \ 8 * $100 + PY0 MOD 8
  DST8 = DST0 + 8
  FOR POS = 1 TO 4
    SRC1 = SRC0
    SRC2 = SRC8
    DST1 = DST0
    DST2 = DST8
    C$ = MID$( T$, POS, 1 )
    IF C$ = " " THEN DIGIT = 10 ELSE DIGIT = VAL( C$ )
    FOR PY1 = 0 TO 9
      POKE DST1, PEEK( SRC1 + 16 * DIGIT )
      POKE DST2, PEEK( SRC2 + 16 * DIGIT )
      IF PY1 = 7 THEN
        ADD SRC1, $100 - 7
        ADD SRC2, $100 - 7
      ELSE
        INC SRC1
        INC SRC2
      END IF
      IF DST1 MOD 8 = 7 THEN
        ADD DST1, $100 - 7
        ADD DST2, $100 - 7
      ELSE
        INC DST1
        INC DST2
      END IF
    NEXT PY1
    ADD DST0, 16
    ADD DST8, 16
  NEXT POS
END SUB
SUB S_AVATAR
  ROTA0 = ( R_ROTA + 0.3926991 ) / 0.785382 MOD 8
  IF S_ROTA <> ROTA0 THEN
    S_ROTA = ROTA0
    AVATAR_SN = 1
    DST = $8000 + 16 * SPRITE.C( AVATAR_SN )
    SRC = ROM( 2 ) + 16 * ( S_ROTA + 244 )
    COPY SRC, 11 TO DST
  END IF
END SUB
SUB S_MAP
  DIM BYTE(7)
  STEP_X = INT( R_LOCX ) - S_LOCX
  STEP_Y = INT( R_LOCY ) - S_LOCY
  IF STEP_X = 1 THEN
    'SCROLL RIGHT.
    ADD S_LOCX, STEP_X
    PY1 = 27
    LOCY2 = S_LOCY + 30
    LOCX0 = S_LOCX + 59
    FOR MAPY = S_LOCY + 3 TO LOCY2
      CX0 = 6
      CLR = S_MAP( LOCX0, MAPY )
      BYTE0 = PEEK( S_ADR0( CX0, PY1 ) )
      BYTE8 = PEEK( S_ADR8( CX0, PY1 ) )
      POKE S_ADR0( CX0, PY1 ), BYTE0 * 2 + CLR MOD 2
      POKE S_ADR8( CX0, PY1 ), BYTE8 * 2 + CLR  \  2
      FOR CX0 = 5 TO 0 STEP -1
        BIT0  = BYTE0 \ $80
        BIT8  = BYTE8 \ $80
        BYTE0 = PEEK( S_ADR0( CX0, PY1 ) )
        BYTE8 = PEEK( S_ADR8( CX0, PY1 ) )
        POKE S_ADR0( CX0, PY1 ), BYTE0 * 2 + BIT0
        POKE S_ADR8( CX0, PY1 ), BYTE8 * 2 + BIT8
      NEXT CX0
      DEC PY1
    NEXT MAPY
  ELSE IF STEP_X = -1 THEN
    'SCROLL LEFT.
    ADD S_LOCX, STEP_X
    PY1 = 27
    LOCY2 = S_LOCY + 30
    LOCX0 = S_LOCX + 4
    FOR MAPY = S_LOCY + 3 TO LOCY2
      CX0 = 0
      CLR = S_MAP( LOCX0, MAPY )
      BYTE0 = PEEK( S_ADR0( CX0, PY1 ) )
      BYTE8 = PEEK( S_ADR8( CX0, PY1 ) )
      POKE S_ADR0( CX0, PY1 ), BYTE0 \ 2 + CLR     * $80
      POKE S_ADR8( CX0, PY1 ), BYTE8 \ 2 + CLR \ 2 * $80
      FOR CX0 = 1 TO 6
        BIT0  = BYTE0 MOD 2
        BIT8  = BYTE8 MOD 2
        BYTE0 = PEEK( S_ADR0( CX0, PY1 ) )
        BYTE8 = PEEK( S_ADR8( CX0, PY1 ) )
        POKE S_ADR0( CX0, PY1 ), BYTE0 \ 2 + BIT0 * $80
        POKE S_ADR8( CX0, PY1 ), BYTE8 \ 2 + BIT8 * $80
      NEXT CX0
      DEC PY1
    NEXT MAPY
  ELSE IF ABS( STEP_Y ) = 1 THEN
    'SCROLL UP OR DOWN.
    ADD S_LOCY, STEP_Y
    IF STEP_Y = 1 THEN
      PY_BEG = 27
      PY_END = 1
      MAPY = S_LOCY + 30
    ELSE
      PY_BEG = 0
      PY_END = 26
      MAPY = S_LOCY + 3
    END IF
    FOR PY1 = PY_BEG TO PY_END STEP -STEP_Y
      FOR CX1 = 0 TO 6
        POKE S_ADR0( CX1, PY1 ), PEEK( S_ADR0( CX1, PY1 - STEP_Y ) )
        POKE S_ADR8( CX1, PY1 ), PEEK( S_ADR8( CX1, PY1 - STEP_Y ) )
      NEXT CX1
    NEXT PY1
    CX0 = 0
    LOCX2 = S_LOCX + 59
    FOR MAPX = S_LOCX + 4 TO LOCX2 STEP 8
      FOR PX0 = 0 TO 7
        BYTE( PX0 ) = S_MAP( PX0 + MAPX, MAPY )
      NEXT PX0
      WORD = S_8080(BYTE(0)) + S_4040(BYTE(1)) + S_2020(BYTE(2)) + S_1010(BYTE(3)) + S_0808(BYTE(4)) + S_0404(BYTE(5)) + S_0202(BYTE(6)) + S_0101(BYTE(7))
      POKE S_ADR0( CX0, PY1 ), WORD
      POKE S_ADR8( CX0, PY1 ), WORD \ $100
      INC CX0
    NEXT MAPX
  ELSE IF STEP_X OR STEP_Y OR S_REDRAW_MAP THEN
    S_REDRAW_MAP = 0
    'REDRAW EVERYTHING.
    ADD S_LOCX, STEP_X
    ADD S_LOCY, STEP_Y
    PY1 = 27
    'MAPY LO AND HI OFFSET BY 3 ROWS BECAUSE SPRITES ARE CENTERED. LOCY2=S_LOCY+PY1+3.
    LOCY2 = S_LOCY + 30
    'MAPX LO AND HI OFFSET BY 4 COLUMNS BECAUSE SPRITES ARE CENTERED. LOCX2=S_LOCX+55+4.
    LOCX1 = S_LOCX + 4
    LOCX2 = S_LOCX + 59
    FOR MAPY = S_LOCY + 3 TO LOCY2
      CX0 = 0
      '(DON'T PIXEL-PLOT THE BOTTOM 4 ROWS OR RIGHT 8 COLS, AS SPRITES ARE CENTERED.)
      FOR MAPX = LOCX1 TO LOCX2 STEP 8
        FOR PX0 = 0 TO 7
          BYTE( PX0 ) = S_MAP( PX0 + MAPX, MAPY )
        NEXT PX0
        WORD = S_8080(BYTE(0)) + S_4040(BYTE(1)) + S_2020(BYTE(2)) + S_1010(BYTE(3)) + S_0808(BYTE(4)) + S_0404(BYTE(5)) + S_0202(BYTE(6)) + S_0101(BYTE(7))
        POKE S_ADR0( CX0, PY1 ), WORD
        POKE S_ADR8( CX0, PY1 ), WORD \ $100
        INC CX0
      NEXT MAPX
      DEC PY1
    NEXT MAPY
  END IF
  'UPDATE MAP GOAL SPRITE 0.
  SPRITE 0, MIN(MAX( 99, S_GOALX-INT(R_LOCX)+128), 156 ), MIN(MAX( 97, INT(R_LOCY)-S_GOALY+112), 126 ),
END SUB
SUB S_MAP_LOAD( CX1, CY1, CX2, CY2, PAL_HIDE, USE_GOAL )
  FOR CY0 = CY1 TO CY2
    FOR CX0 = CX1 TO CX2
      IF ( E_MAP( CX0, CY0 ) AND $0700 ) = PAL_HIDE THEN
        CLR0 = S_TILE2CLR( 0 )
      ELSE
        TILE0 = E_MAP( CX0, CY0 ) MOD $100
        IF E_IS_BOOL( TILE0 ) AND USE_GOAL THEN
          S_GOALX = CX0
          S_GOALY = CY0
          CLR0 = S_TILE2CLR( 0 )
        ELSE
          CLR0 = S_TILE2CLR( TILE0 )
        END IF
      END IF
      S_MAP( CX0 + 32, CY0 + 16 ) = CLR0
    NEXT CX0
  NEXT CY0
END SUB
SUB T_INIT
  DIM BY2CY64(95), BX2BG8009000(39), BX2CX2(39)
  FOR BY0 = 0 TO 95
    BY2CY64( BY0 ) = BY0 \ 3 * 64
  NEXT BY0
  FOR BX0 = 0 TO 39
    BX2BG8009000( BX0 ) = ( BX0 MOD 2 ) * $800 + $9000
    BX2CX2( BX0 ) = BX0 \ 2 * 2
    FOR BY = 0 TO 95
      T_BXY2RAM( BX0, BY ) = BX2BG8009000( BX0 ) + BY2CY64( BY ) + BX2CX2( BX0 )
    NEXT BY
    T_BX2RAM( BX0 ) = T_BXY2RAM( BX0, 95 )
  NEXT BX0
END SUB
SUB T_FADE( IS_OUT )
  IF IS_OUT THEN
    COPY $FF00, 32 TO $A000
    FOR RY = 0 TO 127
      B_P0C0( RY ) = I_P0C0( RY )
    NEXT RY
    FOR ITER = 0 TO 8
      FOR COLR = 0 TO 31
        NUM = PEEK( $FF00 + COLR )
        CALL T_FADE_OUT( NUM )
        POKE $FF00 + COLR, NUM
      NEXT COLR
      FOR RY = 0 TO 127
        CALL T_FADE_OUT( I_P0C0( RY ) )
      NEXT RY
      IF ITER < 8 THEN WAIT 5
    NEXT ITER
  ELSE
    FOR ITER = 0 TO 8
      FOR COLR = 0 TO 31
        NUM = PEEK( $FF00 + COLR )
        CALL T_FADE_IN( NUM, PEEK( $A000 + COLR ) )
        POKE $FF00 + COLR, NUM
      NEXT COLR
      FOR RY = 0 TO 127
        CALL T_FADE_IN( I_P0C0( RY ), B_P0C0( RY ) )
      NEXT RY
      IF ITER < 8 THEN WAIT 5
    NEXT ITER
  END IF
END SUB
SUB T_FADE_OUT( NUM )
  IF NUM AND $30 THEN ADD NUM, -16 ELSE IF NUM AND $0C THEN ADD NUM, -4 ELSE IF NUM AND $03 THEN DEC NUM
END SUB
SUB T_FADE_IN( NUM, OLD )
IF (NUM AND $03)<(OLD AND $03) THEN INC NUM ELSE IF (NUM AND $0C)<(OLD AND $0C) THEN ADD NUM, 4 ELSE IF (NUM AND $30)<(OLD AND $30) THEN ADD NUM, 16
END SUB
SUB T_WIPE_CELL( IS_OUT )
  'TRACK BLOCK COLUMNS.
  DIM BX2CY( 39 )
  FOR BX0 = 0 TO 39
    BX2CY( BX0 ) = 32
  NEXT BX0
  IF IS_OUT THEN COPY $9000, $1000 TO $C000
  FOR ITER = 0 TO 1.25 * 40 * 32
    BX1 = RND( 39 )
    IF BX2CY( BX1 ) THEN
      DEC BX2CY( BX1 )
      BG BX1 AND 1
      CX1 = BX1 \ 2
      IF IS_OUT THEN
        BG SCROLL CX1, 0 TO CX1, 31 STEP 0,1
        CELL CX1, 0, 0
      ELSE
        IF BX1 AND 1 THEN BG SOURCE $C800, 32, 32 ELSE BG SOURCE $C000, 32, 32
        BG COPY CX1, BX2CY( BX1 ), 1, 32 - BX2CY( BX1 ) TO CX1, 0
      END IF
    END IF
    IF ITER MOD 40 = 0 THEN WAIT VBL
  NEXT ITER
  IF IS_OUT THEN
    BG 0
    BG FILL 0, 16 TO 19, 31 CHAR 0
    BG 1
    BG FILL 0, 16 TO 19, 31 CHAR 0
  END IF
END SUB
SUB T_WIPE_BLOCK( IS_OUT )
  'TRACK BLOCK COLUMNS.
  DIM BX2BY( 39 )
  FOR BX0 = 0 TO 39
    BX2BY( BX0 ) = 96
  NEXT BX0
  IF IS_OUT THEN CALL T_BUFFER
  FOR ITER = 0 TO 1.25 * 40 * 96 / 2
    BX1 = RND( 39 )
    IF BX2BY( BX1 ) THEN
      ADD BX2BY( BX1 ), -2
      BY1 = BX2BY( BX1 )
      IF IS_OUT THEN
        'FILL TOP OF WORKING COLUMN $D000.
        FILL $D000, 96 - BY1
        'COPY FROM TOP OF SAVED COLUMN $C000 INTO BOTTOM OF WORKING COLUMN.
        COPY $C000 + 96 * BX1, BY1 TO $D060 - BY1
      ELSE
        'COPY FROM BOTTOM OF SAVED COLUMN $C000 INTO TOP OF WORKING COLUMN.
        COPY $C000 + 96 * BX1 + BY1, 96 - BY1 TO $D000
        'FILL BOTTOM OF WORKING COLUMN $D000.
        FILL $D060 - BY1, BY1
      END IF
      BG BX1 AND 1
      CX1 = BX1 \ 2
      ATTR CELL.A( CX1, 0 )
      'DRAW WORKING COLUMN.
      CALL T_STRIP( CX1 )
    END IF
  NEXT ITER
  IF IS_OUT THEN
    BG 0
    BG FILL 0, 16 TO 19, 31 CHAR 0
    BG 1
    BG FILL 0, 16 TO 19, 31 CHAR 0
  END IF
END SUB
SUB T_DITHER( IS_OUT, COLR )
  IF IS_OUT THEN
    COPY $FF00, 32 TO $A000
    FOR PL = 0 TO 7
      PALETTE PL, , , , COLR
    NEXT PL
    COPY $8000, $400 TO $B000
    RESTORE T_DITHER_OUT
    T_DITHER_OUT:
    DATA %10000000, %00000000, %00000000, %10000000, %00100000, %00000000
    DATA %10000000, %00100000, %01000000, %10010000, %00100000, %01000000
    DATA %10010000, %10100000, %01000000, %10010000, %10100000, %01010000
    DATA %10110000, %10100000, %01010000, %10110000, %11100000, %01010000
    DATA %10110000, %11100000, %11010000, %10110000, %11100000, %11110000
    DATA %10110000, %11110000, %11110000, %11110000, %11110000, %11110000
    FOR ITER = 0 TO 11
      READ MASK0, MASK1, MASK2
      FOR DST = $8000 TO $83FF STEP 16
        POKE DST     , PEEK( DST      ) OR MASK0
        POKE DST +  8, PEEK( DST +  8 ) OR MASK0
        POKE DST +  1, PEEK( DST +  1 ) OR MASK1
        POKE DST +  9, PEEK( DST +  9 ) OR MASK1
        POKE DST +  2, PEEK( DST +  2 ) OR MASK2
        POKE DST + 10, PEEK( DST + 10 ) OR MASK2
      NEXT DST
      IF ITER < 11 THEN WAIT 5
    NEXT ITER
  ELSE
    RESTORE T_DITHER_IN
    T_DITHER_IN:
    DATA %10110000, %11110000, %11110000, %10110000, %11100000, %11110000
    DATA %10110000, %11100000, %11010000, %10110000, %11100000, %01010000
    DATA %10110000, %10100000, %01010000, %10010000, %10100000, %01010000
    DATA %10010000, %10100000, %01000000, %10010000, %00100000, %01000000
    DATA %10000000, %00100000, %01000000, %10000000, %00100000, %00000000
    DATA %10000000, %00000000, %00000000, %00000000, %00000000, %00000000
    FOR ITER = 0 TO 11
      READ MASK0, MASK1, MASK2
      SRC = $B000
      FOR DST = $8000 TO $83FF STEP 16
        POKE DST     , PEEK( SRC      ) OR MASK0
        POKE DST +  8, PEEK( SRC +  8 ) OR MASK0
        POKE DST +  1, PEEK( SRC +  1 ) OR MASK1
        POKE DST +  9, PEEK( SRC +  9 ) OR MASK1
        POKE DST +  2, PEEK( SRC +  2 ) OR MASK2
        POKE DST + 10, PEEK( SRC + 10 ) OR MASK2
        ADD SRC, 16
      NEXT DST
      IF ITER < 11 THEN WAIT 5
    NEXT ITER
    COPY $A000, 32 TO $FF00
  END IF
END SUB
SUB T_DIFFUSE( IS_OUT, COLR )
  IF IS_OUT THEN
    COPY $FF00, 32 TO $A000
    FOR PL = 0 TO 7
      PALETTE PL, , , , COLR
    NEXT PL
    CALL T_BUFFER
  END IF
  J = 0
  REPEAT
    IF J < 3839 THEN
      BX1 = J  \  96
      BY1 = J MOD 96
      CX1 = BX1 \ 2
      CY1 = BY1 \ 3
      BG BX1 AND 1
      ATTR CELL.A( CX1, CY1 )
      IF IS_OUT THEN
        BITS = $03 * 4 ^ ( BY1 MOD 3 )
        CELL CX1, CY1, ( CELL.C( CX1, CY1 ) AND NOT BITS ) OR BITS
      ELSE
        CH = PEEK( $C000 + 96 * BX1 + BY1 )
        IF BY1 MOD 3 = 2 THEN
          MASK = %001111
          CH = 16 * CH
        ELSE IF BY1 MOD 3 THEN
          MASK = %110011
          CH = 4 * CH
        ELSE
          MASK = %111100
        END IF
        CELL CX1, CY1, ( CELL.C( CX1, CY1 ) AND MASK ) OR CH
      END IF
      IF J MOD 96 = 1 THEN WAIT VBL
    END IF
    INC J
    'LFSR TAP BITMASK $C11 ($C11=$800+$400+$10+1, MIRROR OF $883). DEC J INTEGRATED.
    IF J\$800 XOR SGN(J AND $400) XOR SGN(J AND 16) XOR J AND 1 THEN J=J\2-1 ELSE J=J\2+$7FF
  UNTIL J = 0
  IF IS_OUT = 0 THEN COPY $A000, 32 TO $FF00
END SUB
SUB T_COLR( IS_OUT, COLR )
  IF IS_OUT THEN
    COPY $FF00, 32 TO $A000
    MASK = ( COLR XOR %111111 ) AND %010101
    FOR DST = $FF00 TO $FF1F
      POKE DST, ( PEEK( DST ) AND COLR ) + ( PEEK( DST ) \ 2 AND MASK )
    NEXT DST
    FOR RY = 0 TO 127
      B_P0C0( RY ) = I_P0C0( RY )
      I_P0C0( RY ) = ( I_P0C0( RY ) AND COLR ) + ( I_P0C0( RY ) \ 2 AND MASK )
    NEXT RY
  ELSE
    COPY $A000, 32 TO $FF00
    FOR RY = 0 TO 127
      I_P0C0( RY ) = B_P0C0( RY )
    NEXT RY
  END IF
END SUB
SUB T_BUFFER
  'WRITE 2D BLOCK ARRAY (40X96, ROW-SEQUENTIAL) OF COLOR VALUES (0-3) TO $C000.
  DST = $C000
  FOR CX1 = 0 TO 19
    FOR BG1 = 0 TO 1
      BG BG1
      FOR CY1 = 0 TO 31
        CH = CELL.C( CX1, CY1 )
        POKE DST    , CH      AND 3
        POKE DST + 1, CH \  4 AND 3
        POKE DST + 2, CH \ 16 AND 3
        ADD DST, 3
      NEXT CY1
    NEXT BG1
  NEXT CX1
END SUB
SUB T_STRIP( CX1 )
  'SHOW 1D ARRAY (1X96) OF COLOR VALUES FROM $D000
  BY_SRC = $D000
  FOR CY1 = 0 TO 31
    CELL CX1, CY1, PEEK( BY_SRC ) + 4 * PEEK( BY_SRC + 1 ) + 16 * PEEK( BY_SRC + 2 )
    ADD BY_SRC, 3
  NEXT CY1
END SUB
SUB F_INIT
  F_STR$ = " FPS" + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 )
  F_STR$ = F_STR$ + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 )
  F_STR$ = F_STR$ + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 ) + CHR$( 10 )
  F_FRAMES = 29.0
  F_LAP = TIMER - 60
END SUB
SUB F_UPDATE
  INC F_FRAMES
  DURATION = TIMER - F_LAP
  IF DURATION >= 60.000 THEN
    TRACE LEFT$(STR$( INT( F_FRAMES * 600 / DURATION ) / 9.999 ),4) + F_STR$
    F_FRAMES = 0
    F_LAP = TIMER
  END IF
  FRAMES0 = TIMER - F_TIME
  IF FRAMES0 < F_FRAME0 THEN WAIT F_FRAME0 - FRAMES0
  F_TIME = TIMER
END SUB

'CONTROLS
'
'[+] MOVE, [A] SHOOT, TAP [B] USE, [B][+] CIRCLE STRAFE, [B][A] CHANGE WEAPONS
'

'TO DO
'
'ORGANIZE E_IS_DOOR, E_IS_PLAIN, E_IS_BOOL, ETC. TO MORE APPLICABLE ENGINES
'
'UPDATE SOUNDS EVERY VBL IN VOICE-BASED ENGINE, ATTENUATE PER DISTANCE (VOLUME ONLY)
'HALT DOOR ACTIONS DURING PAUSE
'
'WRITE TINY DISPLAY SUBPROGRAM, SHOW PAUSE ENUMERATION IN HUD
'PAUSE WILL CYCLE THROUGH EFFECTS FIRST, THEN TRANSITIONS
'
'VERIFY IF M_M_INIT M_ITER SHOULD BE BASED ON RAD2 NOT RAD1
'TOGGLE SWITCHES
'EASY ENEMY MINIMIZES LOW-DELTA FIRST, HARD ENEMY MINIMIZES HIGH-DELTA FIRST
'DAMAGE DIRECTION ON SUPERELLIPSE OF SCREEN
'HTTPS://GAFFERONGAMES.COM/POST/FIX_YOUR_TIMESTEP/
'MIPMAPS (LAMPS) USE MANUAL BITMASK COLUMNS (DON'T USE PRIO)
'SX-LIB 3D OBJECT RENDERING TOOL WILL PRECALCULATE FIXED ROTATIONS ALONG ONE AXIS
'(CAN'T USE SX-LIB AND HI-RES-LO-CLR DISPLAY SYSTEM)
'

'RAYCASTING
'
'        @@|    |    |    |           VECTORS:
'     |@@@@|    |    |    |    |      TAIL TIP DESCRIPTION
'   ---(R)-+----+----+----+----+--      O   L  <LOC> (LOCATION) OF BIOLOGICAL EYE
'     | |\ |    |    |    |    |        L   P  <<ROT>> (ROTATION) (NOT TO SCALE)
'     | | \|    |    |    |    |        @   S  SCREEN, DEFINED BY <<ROT>> AND FOV
'  ---+-|--\----+----+----+----+---     L   R  RAY, CAST PATH
'     | |  |\   @----@    |    |        *   R  RAY, PERSPECTIVE-CORRECT DEPTH
'     | |  | \  |\XXX|    |    |      TRIANGLES:  
'  ---+-|-@+--Y-+-\XX|----+----+---   POINTS   DESCRIPTION
'     | | |\   \|  \X|    |    |        L@S    PROJECTION
'     | | |Y\   X   \|    |    |        XXX    CAST X, HYPOTINUSE IS UNIT DIST. ON X-AXIS
'  ---+-|-@--@--+\---@----+----+---      Y     CAST Y, HYPOTINUSE IS UNIT DIST. ON Y-AXIS
'     | |  |    | @-----(P)----(S)    NOTES:
'     | |  |    |  \ |   ||    /      * <LOC> AND <<ROT>> ALSO DEFINE IN-GAME USER.
'  ---+-|--+----+---\+---|+---/+---     MOVING AND ROTATING PROJECTION TRIANGLE CHANGES 
'     | |  |    |    \  _|_  / |        IN-GAME USER POSITION AND DIRECTION.
'     | |  |    |    |\/ | \/FOV      * FIRST RAY IS CAST ALONG PATH L-@, LAST RAY IS CAST
'  ---+-|--+----+----+-\-|-/---+---     ALONG PATH L-S. PATH STARTS AT <L>, AND MIGHT HIT
'     | |  |    |    |  \|/    |        A BOX EVEN BEFORE REACHING THE SCREEN PLANE. (NOTE
'     |(*)--------------(L)    |        <<ROT>> IS A UNIT B/C RAY CAN HIT BEFORE SCREEN.)
'   --+----+----+----+--/-+----+--    * TRIANGLES XXX AND Y ARE SHOWN ALIGNED WITH THE
'     |    |    |    ^ /  |    |        BACKGROUND GRID UNIT SPACING, BUT THIS IS ONLY FOR
'          |    |    |/   |             CLARITY AND NOT A RESTRICTION.
'                  -(O)->             * ALL UNITS ARE "BOXES" OR RADIANS UNLESS COMMENTED.
'                    |                
'

'LAYERS AND DRAW ORDER
'
'(SEE S_INIT TOO)
'BG 0 AND 1 BLOXEL DISPLAY, PRIO 0/1 PER-COLUMN, VIA Z-ORDER OF BG VS SX-LIB
'MIPMAP SPRITES PRIO 0 (DUPLICATED HERE TO ALLOW Z-ORDER SORTING WITH SX-LIB SPRITES)
'SX-LIB SPRITES PRIO 0 (THE SPRITE NUMBER FOR THESE IS CONSTANT)
'MIPMAP SPRITES PRIO 1 (DUPLICATED HERE TO ALLOW Z-ORDER SORTING WITH SX-LIB SPRITES)
'ALL NON-SX-LIB SPRITES ARE PRIO 1, NOTE THIS DOES *NOT* EFFECT SPRITE-VS-SPRITE DRAW ORDER
'

'#1:MAIN PALETTES
'
'  PALETTES  COLOR      DESCRIPTION
'                       __IN GAME__
'  0         GRAYSCALE  TILE BACKUP PALETTE (IF NO PALETTE AVALABILE) AND STATUS BAR
'   123456   VARIES     TILE DYNAMIC PALETTE
'         7  CYAN/BLUE  DOOR TILE AND STATUS BAR OPAQUE MASK (OTHERWISE GARBAGE VIA BLOCKS)
'                       __IN GFX DESIGNER BG EDITOR__ (SEE NOTE)
'  0         GRAYSCALE  TILES (DON'T CHANGE COLOR TO LIMIT CONFUSION WITH IN-GAME PALETTE)
'   12 456   VARIES     TILES (PICK ANY COLORS TO ARTISTICLY INDICATE MAP)
'     3      DARK GRAY  TILES, BUT *WON'T* SHOW ON STATUS BAR MAP (USE FOR HIDDEN AREAS)
'         7  CYAN/BLUE  TILES (DON'T CHANGE COLOR TO LIMIT CONFUSION WITH IN-GAME PALETTE)
'                       NOTE: ALL PALETTES ARE OVERWRITTEN IN-GAME, SEE B_LOAD TILE2CLR
'

'#2:MAIN CHARACTERS
'
'  IN-GAME, I.E. ADDRESS $8000
'
'  +---------------+---------------+---------------+---------------+
'  |                                                               | PAGE 1
'  | RAYCAST COLUMN BLOCKS                                         |
'  |                                                               |
'  |                                                               |
'  |                                                               |
'  |                                                               |
'  |                                                               |
'  +---------------+---------------+---------------+---------------+
'  |             / |             / |             / |               | PAGE 2
'  | SX-LIB    /   | SX-LIB    /   | SX-LIB    /   | WEAPONS       |
'  |    4X4  /     |    4X4  /     |    4X4  /     |     4X4       |
'  |       /       |       /       |       /       |               |
'  |     /         |     /         |     /         |               |
'  |   /           |   /           |   /           |               |
'  | /             | /             | /             |               |
'  +-------+-------+-------+---+---+---------------+---------------+
'  |       |               |DK |TRI|                               | PAGE 3
'  | HEART | NUMERALS      |KEY|---+ MAP-LEFT        MAP-RIGHT     |
'  |   2X2 |      4X4      |   |C1 |      4X4              4X4     |
'  +-------+   HEALTH      +---+---+                               |
'  |       |    /AMMO      |LT |C2 |                               |
'  | BULLET|               |KEY|---+                               |
'  |   2X2 |               |   |C3 |                               |
'  +-------+-------+-------+---+---+---------------+---------------+
'  |               |               |               |               | PAGE 4
'  |  MIPMAP       | MIPMAP        | MIPMAP        | MIPMAP        |
'  |     4X4       |    4X4        |    4X4        |    4X4        |
'  |               |               |               |               |
'  |               |               |               |               |
'  |               |               |               |               |
'  |               |               |               |               |
'  +---------------+---------------+---------------+---------------+
'
'
'
'  IN GFX DESIGNER, I.E. ADDRESS ROM(2), FOR USE WITH BG EDITOR (TILEMAPS)
'
'  +-------+-------+---+---+-------+---------------+---------------+
'  |       | START |LMP| * | / | / | DOOR TILES (8)                | PAGE 3
'  |   /   +---+---+---+---+---+---+---------------+---------------+
'  |       |FLR| * | * | * | / | / |    WALL TILES                 |
'  +-------+---+---+---+---+---+---+      (12)     +---+---+---+---+
'  |       | * | * | * | * | / | / |               | * | * | * | * |
'  |   /   +---+---+---+---+---+---+-----------+---+---+---+---+---+
'  |       | * | * | * | * | / | / | DOOR JAMB PSEUDO-TILES (8)    |
'  +-------+-------+---+---+-------+---------------+---------------+
'
'  CHARACTERS INDICATE TILES (SOME TILES DON'T HAVE TEXTURES, OR VICE VERSA)
'  * INDICATES TILE AVAILABLE, / INDICATES TILE UNAVAILABLE
'  START INDICATES PLAYER LEVEL STARTING POSITION, CAN USE FLIP FX AND FY
'  LMP INDICATES LAMP, NOT YET USED
'  FLR INDICATES FLOOR, USED IN STATUS BAR MAP
'  TILE-PAIRS 170-171, 172-173, AND 173-174 ARE FOR BINARY SWITCHES, SOFTWARE WILL SWAP
'    TILE NUMBERS IF [B] 'USE' OCCURS NEAR ONE.
'  DOOR TILES RENDER IN-GAME AS BOTH A DOOR AND DOOR JAMB, SOFTWARE WILL ADD 48 TO DOOR TILE
'    NUMBERS IF A DOOR JAMB NEEDS RENDERED. (DOOR JAMB TILES IN ROM WOULD RENDER PLAINLY.)
'

'#3:MAIN BG
'
'USE THE LOWRES NX GFX DESIGNER TO EDIT TILEMAPS. SOME DATA IS INTERPRETED BY THE SOFTWARE,
'OTHER IS FOR ILLUSTRATION-ONLY, MEANING YOU CAN USE WHATEVER IS ARTISTIC, EASY TO SEE, ETC.
'
'ALL ROM PALETTES ARE FOR ILLUSTRATION-ONLY, AS COLOR REGISTERS (RAM) ARE MODIFIED IN-GAME.
'ALL TILEMAP TILE PALETTES ARE IGNORED EXCEPT PAL=3, USE FOR TILES HIDDEN FROM WORLD MAP.
'FLIP FX,FY ARE FOR ILLUSTRATION-ONLY, EXCEPT FOR STARTING TILES 130-131, AND PRIO TILES.
'ANY TILEMAP TILE WITH PRIO SET WILL BE A HIDDEN PANEL (IT MOVES TWO TILES WHEN USER
'  PRESSES [B]. THE SOFTWARE USES FLIP FX AND FLIP FY TO DETERMINE DIRECTION TO MOVE THE
'  WALL, WHICH *MUST* BE AWAY FROM PLAYER AND TOWARDS TWO EMPTY TILES:
'
'  FX  FY  DIRECTION
'   0   0   POS X
'   0   1   POS Y
'   1   0   NEG X
'   1   1   NEG Y
'

'RAM
'
' ADDRESS  SIZE   DESCRIPTION
'  $A000    8*4   TEMP STORAGE FOR PALETTES DURING TRANSITIONS
'  $B000   64*16  TEMP STORAGE FOR RAYCAST CHAR DATA DURING TRANSITIONS
'  $C000    4KB   TEMP STORAGE FOR BACKGROUNDS DURING TRANSITIONS
'  $D000   32*2   TEMP STORAGE FOR ONE BACKGROUND COLUMN, 32 ROWS HIGH, INCLUDING ATTRIBUTES
'

#1:PALETTES
00152A3F0010252A0024383E0000152A
00000000000000000000000000010A2A

#2:MAIN CHARACTERS
00000000000000000000000000000000
F0000000000000000000000000000000
0000000000000000F000000000000000
F000000000000000F000000000000000
00F00000000000000000000000000000
F0F00000000000000000000000000000
00F0000000000000F000000000000000
F0F0000000000000F000000000000000
000000000000000000F0000000000000
F00000000000000000F0000000000000
0000000000000000F0F0000000000000
F000000000000000F0F0000000000000
00F000000000000000F0000000000000
F0F000000000000000F0000000000000
00F0000000000000F0F0000000000000
F0F0000000000000F0F0000000000000
0000F000000000000000000000000000
F000F000000000000000000000000000
0000F00000000000F000000000000000
F000F00000000000F000000000000000
00F0F000000000000000000000000000
F0F0F000000000000000000000000000
00F0F00000000000F000000000000000
F0F0F00000000000F000000000000000
0000F0000000000000F0000000000000
F000F0000000000000F0000000000000
0000F00000000000F0F0000000000000
F000F00000000000F0F0000000000000
00F0F0000000000000F0000000000000
F0F0F0000000000000F0000000000000
00F0F00000000000F0F0000000000000
F0F0F00000000000F0F0000000000000
00000000000000000000F00000000000
F0000000000000000000F00000000000
0000000000000000F000F00000000000
F000000000000000F000F00000000000
00F00000000000000000F00000000000
F0F00000000000000000F00000000000
00F0000000000000F000F00000000000
F0F0000000000000F000F00000000000
000000000000000000F0F00000000000
F00000000000000000F0F00000000000
0000000000000000F0F0F00000000000
F000000000000000F0F0F00000000000
00F000000000000000F0F00000000000
F0F000000000000000F0F00000000000
00F0000000000000F0F0F00000000000
F0F0000000000000F0F0F00000000000
0000F000000000000000F00000000000
F000F000000000000000F00000000000
0000F00000000000F000F00000000000
F000F00000000000F000F00000000000
00F0F000000000000000F00000000000
F0F0F000000000000000F00000000000
00F0F00000000000F000F00000000000
F0F0F00000000000F000F00000000000
0000F0000000000000F0F00000000000
F000F0000000000000F0F00000000000
0000F00000000000F0F0F00000000000
F000F00000000000F0F0F00000000000
00F0F0000000000000F0F00000000000
F0F0F0000000000000F0F00000000000
00F0F00000000000F0F0F00000000000
F0F0F00000000000F0F0F00000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0103070F1F3F7FFF0000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000103070F1F3F7FFF
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0103070F1F3F7FFF0103070F1F3F7FFF
FF8080808080809FFFFFFFFFFFFFFFE0
FE010101010141F9FFFEFEFEFEFEBE06
FF80808080888F83FFFFFFFFFFF7F0FC
FE0101010121F1F1FFFEFEFEFEDE0E0E
00000000000000000000000000000000
00000000000000000000000000000000
0103070F1F3F7FFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000103070F1F3F7FFF
0000000000000000FFFFFFFFFFFFFFFF
00000000000000000000000000000000
00000000000000000000000000000000
0103070F1F3F7FFF0103070F1F3F7FFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
878080808080807FF8FFFFFFFFFFFF80
F9410101010101FF06BEFEFEFEFEFE00
808080808080807FFFFFFFFFFFFFFF80
E1613131010101FF5E9ECECEFEFEFE00
00000000000000000000000000000000
0103070F1F3F7FFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
00000000000000000000000000000000
00000000000000000103070F1F3F7FFF
0000000000000000FFFFFFFFFFFFFFFF
0000000000000000FFFFFFFFFFFFFFFF
00000000000000000000000000000000
0103070F1F3F7FFF0103070F1F3F7FFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FF8080808090BF82FFFFFFFFFFEFC0FD
FE0101010101FDFDFFFEFEFEFEFE0202
FF8080A3FFA7FFA3FFFFFFDC80D881DC
FE0101F9FDFDFDFDFFFEFE0672820202
0103070F1F3F7FFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
FFFFFFFFFFFFFFFF0000000000000000
00000000000000000103070F1F3F7FFF
0000000000000000FFFFFFFFFFFFFFFF
0000000000000000FFFFFFFFFFFFFFFF
0000000000000000FFFFFFFFFFFFFFFF
0103070F1F3F7FFF0103070F1F3F7FFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
828282828080807FFDFDFDFDFFFFFF80
39190D0D010101FFD6E6F2F2FEFEFE00
818181818280807FFEFEFEFEFDFFFF80
B9998D0D010101FF566672F2FEFEFE00
00001C3E716060400000001C3E3F3F3F
0000387C8E060602000000387CFCFCFC
000000000000000000080C7E7E0C0800
000000000000000000183C7E18181800
00001818183C0000000000247E7E0000
00FE0202020202020000000000000000
007C82BABA827C2800007C44447C0010
80A080000000000080A0800000000000
382424242424241C3C38383838383820
0000FE81817F00000000FFFEFE800000
38383838383838003C2424242424243C
0000FEFEFE0000000000FF8181FF0000
001C1C1C1C1C1C1C3C38383838383820
0000007F7F7F00000000FFFEFE800000
38342C342C342C1C3C38303830383020
0000FED5AB7F00000000FFFED4800000
20100804020100001F0F070301000000
0408102040800000F8F0E0C080000000
0000000000000000FFFFFFFFFFFFFFFF
00000000000000000000000000000000
00000000000000000000000000000000
02020202020202020000000000000000
28282F292B293F001010101614160000
80000000000000000000000000000000
FFD4D497F6969C94006B6B680B6B636B
FFD4C09DD4949494006B415C15555555
FFE484FF9C90FFC4007B7B006F6F007B
FFE480C99480E3C4007B63085541007B
FFE480D5809CE3C4007B6314415D007B
FFE480DD949CE3C4007B631C555D007B
0055555555555555FFAAAAAAAAAAAAAA
0055414955414155FFAAA2889480A2AA
00030F3E7D7FFFFF000001030A185870
00F3FF0CFBFFFFFF0000F3F704000060
40404040404040400000000000000000
00000000000000220000000000000000
00000000000000000000000000000000
02020202020202020000000000000000
007CFEC6C6FE7C3800007C7C7C7C0010
00000000000000008000000000000000
00554155415D4155FFAAA294809CA2AA
FFFFFFFFFFBDFFFFFFFFFFFF00FFFFFF
00183C7E81FFBDFFFFE7C3817E7E7E18
FF99BDFF817E3C18007E7E7E7E81C3E7
000201020000FF000000000000000000
329A22BA0202FE000000000000000000
D1AA8A890000FF000000000000000000
B2AAAAB22202FE000000000000000000
FFFF7B7C3F0F03000307070300000000
FFCF1F7FFFFFF30070F0E08000000000
4040404040407F000000000000000000
322A26220000FF000000000000000000
ADAAAA6A0000FF000000000000000000
1AB28AB20202FE000000000000000000
38383F3F3F3F3F001010101614160000
80000000000000008000000000000000
382424242424241CBE79BA79BA79BA61
0000FE81817F0000AA55FFFEFE80AA55
3838383838383800BE65A665A665A67D
0000FEFEFE000000AA55FF8181FFAA55
001C1C1C1C1C1C1CBE79BA79BA79BA61
0000007F7F7F0000AA55FFFEFE80AA55
38342C342C342C1CBE79B279B279B261
0000FED5AB7F0000AA55FFFED480AA55
FF8080808080809F007F7F7F7F7F7F7F
FE010101010141F901FFFFFFFFFFFFFF
FF80808080888F83007F7F7F7F7F7F7F
FE0101010121F1F101FFFFFFFFFFFFFF
7CFEC6CEDEF6E6C67CFEC6CEDEF6E6C6
18383818181818181838381818181818
7CFEC60E1C3870E07CFEC60E1C3870E0
7CFEC6063C3C06C67CFEC6063C3C06C6
36366666FEFE060636366666FEFE0606
FEFEC0C0FCFE0606FEFEC0C0FCFE0606
7CFEC6C0FCFEC6C67CFEC6C0FCFEC6C6
FEFE06060C0C1818FEFE06060C0C1818
7CFEC6C67C7CC6C67CFEC6C67C7CC6C6
7CFEC6C6FE7E06067CFEC6C6FE7E0606
00000000000000000000000000000000
00FE0202020202020000000000000000
878080808080807F7F7F7F7F7F7F7FFF
F9410101010101FFFFFFFFFFFFFFFFFF
808080808080807F7F7F7F7F7F7F7FFF
A1613131010101FFFFFFFFFFFFFFFFFF
FE7C000000000000FE7C000000000000
18180000000000001818000000000000
FEFE000000000000FEFE000000000000
FE7C000000000000FE7C000000000000
06060000000000000606000000000000
FEFC000000000000FEFC000000000000
FE7C000000000000FE7C000000000000
30300000000000003030000000000000
FE7C000000000000FE7C000000000000
06060000000000000606000000000000
00000000000000000000000000000000
02020202020202020000000000000000
FF8080808090BF82007F7F7F7F7F7F7F
FE0101010101FDFD01FFFFFFFFFFFFFF
FF8080A3FFA7FEA3007F7F7F7F7F7F7F
FE0101F98D7DFDFD01FFFFFFFFFFFFFF
60A0A0C0060A0A0C60A0A0C0060A0A0C
40404040040404044040404004040404
C06080E00C06080EC06080E00C06080E
C06020C00C06020CC06020C00C06020C
A0E020200A0E0202A0E020200A0E0202
E0C020C00E0C020CE0C020C00E0C020C
8080E0E008080E0E8080E0E008080E0E
E02040400E020404E02040400E020404
E0E0A0E00E0E0A0EE0E0A0E00E0E0A0E
E0A0E0200E0A0E02E0A0E0200E0A0E02
00000040000000040000004000000004
2ABA0A8A0202FE000000000000000000
828282828080807F7F7F7F7F7F7F7FFF
29190D0D010101FFFFFFFFFFFFFFFFFF
818181818280807F7F7F7F7F7F7F7FFF
A9998D0D010101FFFFFFFFFFFFFFFFFF
80A080000000000080A0800000000000
20804000000000002080400000000000
4000E000000000004000E00000000000
80204000000000008020400000000000
20A020000000000020A0200000000000
40208000000000004020800000000000
E000400000000000E000400000000000
40802000000000004080200000000000
0D0A08080000FF000000000000000000
2C8AAAAC0800FF000000000000000000
D1AA8A890000FF000000000000000000
B2AAAAB22202FE000000000000000000

#3:MAIN BG
00004040000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
0000000000000000000000009E029E02
9E029F029E029E029E029E029E029F02
9E029E029E0200000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A03
9A039A039A039A039A03000000000000
00000000000000000000000000000000
0000000000000000000000009E029200
92009200920092009200920092009200
920092009E0200000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A03
92039203920392039A03000000000000
0000000000009A009A009A009A009A00
9A009A009D009A009A009A009F029200
92009200920092009200920092009200
920092009F029E029E029E029E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A03
92039203920392039A039A0300000000
0000000000009A009200920092009200
9200920092009200920092009E029200
92009200920092009200920092009200
920092009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A03
920392039203920392039A0300000000
0000000000009A009200840092009200
92009200840092009200920088079200
92009200920092008400920092009200
9200920088079200920092009F020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A03
920392039203920392039A0300000000
0000000000009A009200920092009200
9200920092009200920092009E029200
92009200920092009200920092009200
920092009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A00
9A009B009A009A009C309A009A009B00
9A009A0000009A009200920092009A00
9A009A009D009A009A009A00A8029200
92009200920092009200920092009200
92009200A8029E029E029E029E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A00
92009200920092009200920092009200
92009A0000009A009200920092009A00
0000000000000000000000009E029200
92009200920092009200920092009200
920092009E0200000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009D00
92009200920092009200920092009200
92009D009A009A009200920092009A00
9A009A0000000000000000009E029E02
9E029F029E029E0289079E029E029F02
9E029E029E0200000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A00
92009200920092009200920092009200
92009A00920092009200920092009200
92009A00000000000000000000000000
000000009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A00
92009200920092009200920092009200
92008807920092009200840092009200
92009A00000000000000000000000000
000000009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000009A00
92009200920092009200920092009200
92009A00920092009200920092009200
92009A00000000000000000000000000
00000000A802920084009200A8020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009A009A009A009A009D00
92009200920092009200920092009200
92009D009A009A009A009B009A009A00
9A009A00000000000000000000000000
000000009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200920092009A009A00
92009200920092009200920092009200
92009A00000000000000000000000000
00000000000000000000000000000000
000000009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200840092009A009A00
9A009B009A009A0089079A009A009B00
9A009A00000000000000000000000000
000000000000000000009E039E039E03
9E029E029E029200920092009E029E02
9E020000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200920092009A000000
000000009A009200920092009A000000
00000000000000000000000000000000
000000000000000000009E0392039203
9F2A9200920092008400920092009200
9E020000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009A0089079A009A000000
000000009D009200840092009D000000
00000000000000000000000000000000
000000000000000000009E0392039203
9E029E029E029200920092009E029E02
9E020000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200920092009A009A00
9A009A009A009200920092009A000000
00000000000000000000000000000000
000000000000000000009E0392039203
9E039E039E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200840092009A009200
920092009A009200920092009A000000
00000000000000000000000000000000
000000000000000000009E0392039203
9E039E039E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A0092009200920092009200
840092009D009200840092009D000000
00000000000000000000000000000000
000000000000000000009E039E039E03
9E039E039F029200840092009F020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200920092009A009200
920092009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009E029200920092009E020000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000009A009200920092009A009A00
9A009A009A009A0089079A009A009A00
9A009A00000000000000000000000000
00000000000000000000000000000000
00009A009E029F0289079F029E029A00
00000000000000000000000000000000
00000000000000000000000000009807
98079807980798079807980798079807
980700009D009200840092009D009A00
92009200920092009200920092009200
92009A00000000000000000000000000
00000000000000009A009A009A009A00
9D009A00920092009200920092009A00
9D009A009A009A009A00000000000000
00000000000000000000000000009807
92009200920092009200920092009200
980700009A009200920092009A009A00
92009200920092009200920092009200
92009D00000000000000000000000000
00000000000000009A00920092009200
92009200920092009200920092009200
92009200920092009A00000000000000
00000000000000000000000000009807
92009200920092009200920092009200
980700009A009200920092009A009A00
92009200840092009200920084009200
92009A00000000000000000000000000
00000000000000009B00920092009200
92009200920092009200920092009200
92009200920092009B00980798079807
98079807980798079807980798079807
92009200920092009200920092009200
980700009A0092009200920092009A00
92009200920092009200920092009200
92009A00000000000000000000000000
00000000000000009A00920092009200
92009200920092009200920092009200
92009200920092009200980792009200
92009200920092009200920092009807
92009200920092009200920092009200
980700009A0092009200920092008807
92009200920092009200920092009200
92009D00000000000000000000000000
00000000000000009A00920092008400
92009200920092008400920092009200
92008400920092009200880792009200
92009200920092009200920092008807
92009200920092009200920092009200
990700009A0092009200920092009A00
92009200920092009200920092009200
92009A00000000000000000000000000
00000000000000009A00920092009200
92009200920092009200920092009200
92009200920092009200980792009200
92009200920092009200920092009807
92009200920092009200920092009200
980700009A009200920092009A009A00
92009200840092009200920084009200
92009A00000000000000000000000000
00000000000000009B00920092009200
92009200920092009200920092009200
92009200920092009B00980798079807
92009200920092009807980798079807
92009200920092009200920092009200
980700009A009200920092009A009A00
92009200920092009200920092009200
92009D00000000000000000000000000
00000000000000009A00920092009200
92009200920092009200920092009200
92009200920092009A00000000009807
98079200920098079807000000009807
92009200920092009200920092009200
980700009A009200920092009A009A00
92009200920092009200920092009200
92009A00000000000000000000000000
00000000000000009A009A009C009A00
9A009A00920092009200920092009A00
9A009C009A009A009A00000000000000
98079200920098070000000000009807
92009200920092009200920092009200
980700009C009200840092009C009A00
9A009A009A009A0089079A009A009A00
9A009A00000000000000000000000000
00000000000000000000000000000000
00009A00980798078907980798079A00
00000000000000000000000000000000
98079200920098070000000000009807
98079807920098079807920098079807
980700009A009200920092009A009A00
9A009A009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079200920098070000000000000000
00009807980798079807980798070000
000000009A009200920092009A009A00
9A009A009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792008400920098070000
00000000000000000000000000000000
98079200920098070000000000000000
00000000000000000000000000000000
000000009A009200920092009A009200
920092009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079200920098070000980798079807
98079807980798079807980700000000
000000009A0092009200920092009200
840092009D009200840092009D000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079200920098079807980792009807
92009807920098079200980798070000
000000009A009200920092009A009200
920092009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079200920092009807920092009200
92009200920092009200920098070000
000000009A009200840092009A009A00
9A009A009A009200920092009A000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000980792008400920098070000
00000000000000000000000000000000
98079200920092008807920092009200
92009200920092009200920099070000
000000009A009200920092009A009A00
9A009A009A009200920092009A009A00
9A009A009A009A009A009A009A009B00
9A009A009A0000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079200920092009807920092009200
92009200920092009200920098079A03
9A039A039A0092009200920092009200
92009200920092009200920092009200
9200920092009A009200920092009200
920092009D00A901A901000000000000
00000000980792009200920098070000
00000000000000000000000000000000
98079807980798079807980792009807
92009807920098079200980798070000
00009A039A0092009200920092009200
84009200920092009200920092009200
84009200920088079200920092009200
920092008E019200AA01000000000000
00000000980792009200920098070000
00000000000000000000000000000000
00000000000000000000980798079807
98079807980798079807980700000000
00009A039A0092009200920092009200
92009200920092009200920092009200
9200920092009A009200920092009200
920092009D00A901A901000000000000
00000000980792008400920098070000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A009A009A009A009A009A00
9A009A009A009A009C009A009A009A00
9A009A009A009A009A389A009A009B00
9A009A009A0000000000000000000000
00000000980792009200920098070000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
000000000000A903A9039D0392039203
9A03920392039A2B920392039A030000
00000000000000000000980798079807
98079807980798078907980798079807
98079807980798070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
000000000000AA0392038E0392039203
9A03920392039A0392039A039A030000
00000000000000000000980792009200
92009200980792009200920098079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
000000000000A903A9039D0392039203
9203920392039A039A039A0300000000
00000000000000000000980792009200
92009200880792008400920088079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
000000000000000000009A039A039A3B
9A039A039A039A030000000000000000
00000000000000000000980792009200
92009200980792009200920098079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
0000000000000000000000009A039203
92039A03000000000000000000000000
00000000000000000000980792009200
92009200980792009200920098079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
0000000000000000000000009A039203
92039A03000000000000000000000000
00000000000000000000980798079807
9E329807980792009200920098079807
98079807980798070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
0000000000000000000000009A039A03
9A039A03000000000000000000000000
00000000000000000000980792009200
92009200980792009200920098079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
000000000000000000009E2A92008202
92009200880792008400920088079200
9200920092009E220000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000980792009200
92009200980792009200920098079200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000009803000099030000
9A0300009B0300009C0300009D030000
9E0300009F0300000000980798079807
9E3A9807980792009200920098079807
98079807980798070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000980792009200
92009200920092009200920092009200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
0000000000000000A8030000A9030000
AA030000AB0300000000000000000000
00000000000000000000980792008400
92009200920092008400920092009200
92008400920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000980792009200
92009200920092009200920092009200
92009200920098070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000009A0389039A030000
9A038B039A0300009A038D039A030000
9A038F039A0300000000980799079807
98079907980798079907980798079907
98079807990798070000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000008803000000000000
8A030000000000008C03000000000000
8E030000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000009A03000000000000
9A030000000000009A03000000000000
9A030000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A039A0300000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00009A03980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803980398039803980398039803
98039803

#4:TEXTURES
DB7EC37272C37EDB24FF7EDFDF7EFF24
C318A53C3CBD00DB3CE75AC3D342FF24
D1040E606E0400DB2EFFFFBFBFFFFF24
EEE0CE0EECE0EECC911F39F1931F1933
00FEFEAAAAFEAAAAFFFF83D7D7ABD7D7
FFFF94B4D49C9596FF006B6B6B6B6B6B
FFDBAD99BDBD99C3FFE7D3FFF7EFFFFF
FFBDBDBDBDB981FFFFC3FBDBFFCFFFFF
EEEE007777003B3B9911FFCC88FFE4C4
EE00BB007700DD0011FF44FF88FF22FF
A28AA82AA28AA82A5D7557D55D7557D5
81FF7E7E766E7E7E7EBD8199BDBD9981
810081003C8100817EFF7EFFFF7EFF7E
180042007E3C1800E7FFBDFFFFFFFFFF
183C7E0042001800E7C381FFFFFFFFFF
997EFF7E7EFF7E9966E766E7E766E766

#5:TEXTURES 2X2
0052005F10105E1EFFADFFBFFFFFB1F5
004A00FA08080A08FFB5FFFDFFFFFDFF
0052005F1016591FFFADFFBFFFF9B6F0
004A00FA08080A08FFB5FFFDFFFFFDFF
0011387D017D3911FFFEFFFEFEFEFEFE
007D7C39399393C7FF8283C6C66C6C38
FFFF82FFFF191111007D7D00E6EEEEEE
FFFD27E527E7E42400DAD81AD81BDBDB
FF829FFF1A1A1A1F007D7F10F5F5F5F0
FF21FDFDAFACACAC00DEFE0654575757
FFFF00FF888A8D8800FFFF0077777777
FFFF00FF888A8D8800FFFF0077777777
FFF1C3C1DFC7C3C3FFFEFCFEE0F9FCFE
FF8FC383FBE3C343FF7F3F7F871F3FFF
FFC0C0C0C3C7C7C7FFFFFFFFFCFFFFFD
FF030303E3E3E3E3FFFFFFFF1F9FDFDF
1E5E10105F005200F5B1FFFFBFFFADFF
080A0808FA004A00FFFDFFFFFDFFB5FF
1F5F1F105F005200F4B4F0FFBFFFADFF
080A0808FA004A00FFFDFFFFFDFFB5FF
01091D0941005500FEF6EAF6BEFFAAFF
C7939339397C7D00386C6CC6C68382FF
131F11FFFD878784ECE0EE007A787B7B
242424FF3FE1E121DBDBDB00DE1EDEDE
1F1F1FFA9A9A9A9AF2F2F01575757575
ACACACAFADADADAD5757575456565656
A8D88888888A8D887777777777777777
A8D88888888A8D887777777777777777
C7CFCECECFC7C3F0FFFFF5FFFEFFFEFF
E3F37373F3E3C30FFF7FFFAFFFFFFFFF
C7C7C7C7C0C0C0FFFFFFF9FFFFFFFFFF
E3E3E3C3030303FFFFFFFFFFFFFFFFFF
FFFFE223F3F33FE7001DDDDC0CCCC01B
FFFF20E03F2FE8EF00DFDF1FC0D71790
FF808080FF080808007F7F7F00F7F7F7
FF808080FF080808007F7F7F00F7F7F7
F88888888F8888880777777770777777
F88888888F8888880777777770777777
C0FFFF18080F1F1F3F9FCFE7F7F0E3E7
03FFFF1810F078F8FCF9F3E7EF0FC7E7
80000000008000007FFFFFFFFF7FFFFF
0100000000010000FEFFFFFFFFFEFFFF
000000010307101FFFFFFFFEFCF8EFE0
00000080C0E008F8FFFFFF7F3F1FF707
000F18111317101FFFF0E7EFEFEFEFE0
00F01888C8E808F8FF0FE7F7F7F7F707
8579494949CD49497AFEFEFEFE7AFEFE
A19E929292B392925E7F7F7F7F5E7F7F
2426272724E7FF00DBD9D8DBDB18C0FF
6929FFFF0181FF91D6D600FEFE7E006E
FF808080FF080808007F7F7F00F7F7F7
FF808080FF080808007F7F7F00F7F7F7
F88888888F8888880777777770777777
F88888888F8888880777777770777777
1F151F1E1F1E0F00EFEEEEEFE7E3F0FF
78F8A8F8F8F8F000F77777F7E7C70FFF
3F3F840000000080FFFF7BFFFFFFFF7F
FCFC110000000001FFFFEEFFFFFFFFFE
1F10171311180F00E0EFEFEFEFE7F0FF
F808E8C88818F00007F7F7F7F7E70FFF
1F10070301000000E0EFF8FCFEFFFFFF
F808E0C08000000007F71F3F7FFFFFFF
4949CD4949497985FEFE7AFEFEFEFE7A
9292B39292929EA17F7F5E7F7F7F7F5E

#15:MAIN SOUND
3800336A000000001800846C003A0000
08006060000000002800303019FE0000
38002020000000003800505000000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000
0800000F000000000800000F00000000

